Android Splash Screen с сетевой нагрузкой и минимальным временем отображения заставки

В настоящее время я использую приведенную ниже структуру в своих действиях на заставке, чтобы показать ее в течение определенного периода времени:

    new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
            startMainActivity();
       }
    }, SPLASH_DISPLAY_LENGHT);

Однако я просто создаю приложение, которое загружает некоторую информацию на свой экран-заставку из сети, используя AsyncTask следующим образом:

startUpAsyncTask = new StartUpAsyncTask(this);
startUpAsyncTask.execute();

Теперь я хочу реализовать Handler так, чтобы:

  1. Если во время загрузки сети что-то пошло не так, обработчик останавливается, чтобы перейти к MainActivity.
  2. Если загрузка сети длится дольше, чем SPLASH_DISPLAY_LENGHT, действие ожидает, пока загрузка сети завершится через StartUpAsyncTask, а затем переходит к следующему действию.
  3. Если сеть StartUpAsyncTask завершает работу очень скоро, экран-заставка отображается не менее SPLASH_DISPLAY_LENGHT времени.

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


person VSB    schedule 11.09.2015    source источник


Ответы (2)


Вы можете зарегистрировать BroadcastReceiver, зарегистрированного с LocalBroadcastManager, на экране-заставке, который получит успешное сообщение от вашего AsyncTask и установит флаг. Еще один BroadcastReceiver будет зарегистрирован в вашем обработчике на случай, если флаг еще не установлен, когда SPLASH_DISPLAY_LENGHT уже прошел и будет startMainActivity() при получении трансляции от вашего AsyncTask; в противном случае, если флаг уже установлен, когда SPLASH_DISPLAY_LENGHT завершается в вашем обработчике, он будет непосредственно startMainActivity().

В вашем SplashActivity:

private class SplashActivity extends Activity {
    public static final String ACTION_DATA_LOADING_COMPLETE = "com.example.myapp.ACTION_DATA_LOADING_COMPLETE";

    private LocalBroadcastManager localBroadcastManager;

    private boolean dataLoadingComplete = false;

    @Override
    private void onCreate(Bundle savedInstanceState) {
        ...

        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        localBroadcastManager .registerBroadcastReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                dataLoadingComplete = true;
            }
        }, new IntentFilter(ACTION_DATA_LOADING_COMPLETE));

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                localBroadcastManager.registerBroadcastReceiver(new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        startMainActivity();
                    }
                }, new IntentFilter(ACTION_DATA_LOADING_COMPLETE));

                if (dataLoadingComplete)
                    localBroadcastManager.sendBroadcast(new Intent(ACTION_DATA_LOADING_COMPLETE));
            }
        }, SPLASH_DISPLAY_LENGHT);
    }
}

В вашем AsyncTask:

@Override
onPostExecute(...) {
    super.onPostExecute(...)

    ...

    LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(SplashActivity.ACTION_DATA_LOADING_COMPLETE));
}
person Kamran Ahmed    schedule 11.09.2015

поместите условие в обработчик, как это

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
            if(isTaskSuccessfull)
            startMainActivity();
            else
                isHandlerTimeout = true;
       }
    },

в методе Asyn OnPost() сначала измените значение флага (isTaskSuccessfull) на true из задачи asyn, когда задача будет успешно завершена, затем проверьте, истинно ли значение isHandlerTimeout, если это так, вызовите метод startMainActivity() из onPost() asyn.

person Arun Singh Bisht    schedule 11.09.2015