0

РедактироватьAndroid SplashScreen без создания нового вида деятельности

После перемещения моего кода загрузки/создания к асинхронному задаче (см ниже) - я до сих пор первоначальным проблемы, которые я имел с моим оригинальным SplashScreen.

Те в том, что:

1) При запуске задачи Async в OnCreate, все загружается, но мой диалог может быть показан только тогда, когда OnStart() вызывается, что делает весь процесс своего рода бессмысленно, поскольку там это длинная пауза с пустым экраном, после того, как все загрузилось, перед тем, как исчезнуть, начнет мигать диалог «загрузка».

2) Я не могу перемещать загрузку/создание объекта и т. Д. В onStart, потому что он будет запущен снова, даже когда приложение будет возобновлено после отправки на задний план, который я не хочу, и б) когда при вызове восстановления сохраненногоInstanceState в onCreate() я получаю исключение nullPointerException, потому что я восстанавливаю свойства объектов, которые еще не были созданы.

Было бы очень полезно, если бы кто-нибудь мог посоветовать, как обойти эти проблемы и создать простой заставку. Благодаря!

фон

Мое приложение использует только один вид деятельности, и я хотел бы сохранить его таким образом, если это возможно.

Я боролся с этим больше недели, поэтому надеюсь, что кто-то может мне помочь.

Все, что я хочу сделать, это использовать SplashScreen с простым сообщением «загрузки» отображаются на экране во время загрузки мои ресурсы (и создаются объекты и т.д.) Есть несколько пунктов:

Условия

1) SplashScreen должен не иметь свою собственную деятельность - все должно содержаться в одиночной деятельности

2) SplashScreen должен не используйте XML-макет (я создал класс Splashscreen, который использует View для отображения загружающего PNG)

3) Мое приложение - openGL ES 2.0, поэтому текстуры необходимо загружать в поток OpenGL (создание объектов и т. д., которые не 't использовать вызовы GL - это нормально, если нужно, при необходимости использовать другой поток).

То, что я пытался до сих пор

То, что я сделал до сих пор было создать диалоговое окно и отобразить его в моем OnStart() метод с:

Dialog.show(); 

тогда пусть все нагрузки в мой onSurfaceCreated метод перед тем, как избавиться от него с:

Dialog.dismiss(); 

Однако мне нужно было изменить это по причинам varioius так что теперь я Ĉ повторно привяжите мои объекты к вызову в моем методе onCreate() и просто загрузите текстуры в мой метод GLS Renderer onSurfaceCreated.

Однако, это означает, что, поскольку диалог не отображается до тех пор, после OnCreate, я все еще получаю задержку (пустой экран) в то время как все создано перед тем плеск экран отображается, это то остается на до тех пор, пока текстуры не загрузятся. Есть и другие проблемы, которые могут подождать еще один день!

Таким образом, мой подход неправдоподобен. Я читал каждый урок, который мог, и каждый связанный с заставкой вопрос, который я мог найти на SO и Gamedev.SE, но я все еще не могу найти объяснения (что имеет смысл для меня), как это можно достичь.

Я надеюсь, что кто-то здесь сможет объяснить.

+0

У вас есть попытки использовать фрагменты? – amalBit

ответ

0

Вы должны быть в состоянии использовать AsyncTask для загрузки ресурсов в фоновом режиме, а затем просто отпустить выплеск

Вот AsyncTask, который я использую для загрузки данных из удаленного дб. Это показывает загрузки прогресса круг, пока задача не будет завершена, но должна быть легко повторно предназначена для отображения вашего всплеска

AsyncTask, который работает в фоновом режиме

private class SyncList extends AsyncTask<Void, ULjException, Void> { 

    private static final String TAG = "SyncList"; 

    private final class ViewHolder { 
     LinearLayout progress; 
     LinearLayout list; 
    } 

    private ViewHolder m; 

    /** 
    * Setup everything 
    */ 
    protected void onPreExecute() { 
     Log.d(TAG, "Preparing ASyncTask"); 
     m = new ViewHolder(); 
     m.progress = (LinearLayout) findViewById(R.id.linlaHeaderProgress); 
     m.list = (LinearLayout) findViewById(R.id.listContainer); 

     m.list.setVisibility(View.INVISIBLE); //Set the ListView that contains data invisible 
     m.progress.setVisibility(View.VISIBLE); //Set the loading circle visible you can sub in Dialog.show() here 
    } 

    /** 
    * Async execution performs the loading 
    */ 
    @Override 
    protected Void doInBackground(Void... arg0) { 
     try { 
      Log.d(TAG, "Syncing list in background"); 
      dba.open(ListActivity.this); 
      dba.sync(); 
     } catch (ULjException e) { 
      publishProgress(e); 
     } 
     return null; 
    } 

    /** 
    * Display exception toast on the UI thread 
    */ 
    protected void onProgressUpdate(ULjException... values) { 
     Log.e(TAG, values[0].getMessage()); 
     Toast.makeText(ListActivity.this, "Sync failed", Toast.LENGTH_LONG).show(); 
    } 

    /** 
    * Finish up 
    */ 
    protected void onPostExecute(Void result) { 
     Log.d(TAG, "ASyncTask completed, cleaning up and posting data"); 
     fillData(); 
     m.list.setVisibility(View.VISIBLE); //Show the list with data in it 
     m.progress.setVisibility(View.INVISIBLE); //Hide the loading circle sub in Dialog.dismiss() 
    } 
} 

Calling Задаче

protected void onStart() { 
    super.onStart(); 
    // Init the dba 
    dba = DBAccessor.getInstance(); 
    new SyncList().execute(); 
} 

Следует отметить, что AsyncTask является внутренним классом Activity, связанным с этим здесь

Редактировать
OnCreate Метод

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_layout); 

    Dialog.show(); 
    //This launches a new thread meaning execution will continue PAST this call 
    //to onStart and your loading will be done concurrently 
    //Make sure to not try to access anything that you're waiting to be loaded in onStart or onResume let your game start from onPostExectue 
    new AsyncTask.execute(); 
} 

doInBackground

protected Void doInBackground(Void... arg0) { 
    Load all resources here 
} 

onPostExecute

protected void onPostExecute(Void result) { 
    Dialog.dismiss(); 
    Call a method that starts your game logic using your newly loaded resources 
} 
+0

Спасибо @jhorvat вы могли бы объяснить немного больше, как это поможет? Теперь я реализую простую задачу Async, но у меня все еще есть пара проблем.Во-первых, я запускаю задачу в своем onCreate(), поэтому она отключается и начинает создавать мои объекты, но остальная часть кода продолжается, и я получаю нулевой указатель, потому что создание объекта еще не завершено. Также, я могу показать свой диалог здесь? Я понимаю, что если я сделаю Dialog.show() из onCreate, он не будет отображаться до тех пор, пока onStart(); - Это также случай, когда вы показываете его из задачи Async или у меня все это неправильно? Спасибо за вашу помощь. – Zippy

+0

Вы хотите переместить любые вызовы, зависящие от инициализируемых объектов, к методу 'onPostExecute'. Вы можете показать диалог в 'onPreExecute' и скрыть его в' onPostExecute' ('doInBackground' не имеет доступа к потоку пользовательского интерфейса). Дело в том, что в AsyncTask ваши обновления пользовательского интерфейса (показывающие/скрывающие диалог) не будут блокироваться загрузкой ресурсов, потому что нагрузки будут выполняться в другом потоке. Это должно устранить проблему с пустым экраном. Кроме того, в дальнейшем он дает вам возможность отображать индикатор выполнения на всплеске, чтобы указать прогресс для ваших пользователей, если вы хотите – jhorvat

+0

Если показ диалога в 'onPreExecute' не работает с вызовом в вашем' onCreate', прежде чем вы начнете выполнение задачи но вы все равно должны «отклонять» его в 'onPostExecute', поскольку этот метод всегда будет выполняться, как только завершится« doInBackground »AsyncTask. – jhorvat