2015-10-25 2 views
1

Я пишу свое первое приложение для Android. У меня есть ExpandableListView на моей основной компоновке, которая занимает некоторое время, чтобы загрузить (~ 5 секунд). Мне нужно вызвать статический метод до или после того, как пользовательский интерфейс был отображен теоретически, но этот метод абсолютно должен иметь возможность отображать AlertDialog. Из моих тестов пользовательский интерфейс должен отображаться до отображения любого AlertDialog, что имеет смысл.Android - Запуск UI-зависимого кода сразу после завершения основного макета

С моей точки зрения, приложение отображает пользовательский интерфейс, когда возвращается onResume(). Однако, кажется, нет никакого простого способа выполнить код в потоке пользовательского интерфейса сразу после того, как onResume() вернется, чтобы я мог отображать AlertDialog, кроме использования onPostExecute() от AsyncTask, который должен быть возвращен до того, как он отобразит любое графическое диалоговое окно/Toast from мои тесты, которых я не могу.

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

Edit: Код

@Override 
protected void onResume() 
{ 
    super.onResume(); 
    MessageQueue.IdleHandler h = new MessageQueue.IdleHandler() 
    { 
     @Override 
     public boolean queueIdle() 
     { 
      AlertDialog.Builder dlgAlert = new AlertDialog.Builder(getBaseContext()); 
      dlgAlert.setMessage("This is an alert with no consequence"); 
      dlgAlert.setTitle("App Title"); 
      dlgAlert.setPositiveButton("OK", null); 
      dlgAlert.setCancelable(true); 
      dlgAlert.create().show(); 
      return true; 
     } 
    }; 
    this.getMainLooper().myQueue().addIdleHandler(h); 
} 
+0

5s загрузить вид ... Я надеюсь, что вы не делаете это на UI тему. Вы можете попробовать вызвать метод runOnUIThread прямо перед возвратом onResume. –

+0

пытался использовать 'Handler' в' onResume'? – pskink

+0

@ KamenStoykov благодарит за ваш ответ; Я попробовал 'runOnUIThread' прямо перед' onResume() ', но пользовательский интерфейс все еще не отображается в момент запуска моего метода. Я попробую «Handler» позже, когда я получу шанс. –

ответ

1

Я нашел решение; он работает, но я уверен, что это может стать лучше/элегантнее. Повторить цель: мне нужно запустить код, который отображает Dialogs сразу после отображается основной макет основного вида деятельности.

Что делает этот код: Этот код позволяет выполнять MyClass.doTask(args), если пользователь нажимает кнопку положительный в AlertDialog прямо после того, как отображается основной макет и показать ProgressDialog, пока задача не будет завершена.

В вашей рабочей нити вы также можете использовать static HashMap<Dialog, Boolean> или что-то подобное, чтобы легко отслеживать состояния всех встроенных диалогов, если у вас их много, но для этого вам нужно static.

В вашем основном классе активности:

private static boolean staticInitializerFired = false; 
private static MyType staticArg = myVal; 

@Override 
protected void onResume() 
{ 
    super.onResume(); 
    if(!staticInitializerFired) 
    { 
     staticInitializerFired = true; 
     final Context ctx = this; 
     Thread t = new Thread() 
     { 
      @Override 
      public void run() 
      { 
       MyClass.staticMethod(ctx, staticArg); 
      } 
     }; 
     t.start(); 
    } 
} 

В MyClass:

private static boolean dlg0Showing = true; //preset initial state so worker thread is notified correctly before the dialog is actually built and shown in the UI thread 
private static boolean dlg1Showing = false; 
private static ProgressDialog progressDialog; 
private static void showDialogAndDoTask(final Context context) 
{ 
    ((Activity)context).runOnUiThread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      AlertDialog dlg = new AlertDialog.Builder(context).create(); 
      dlg.setMessage("My message... Yes/No ?"); 
      dlg.setCancelable(false); 
      dlg.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", 
        new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int id) 
         { 
                dlg1Showing = true; 
        dlg0Showing = false; 

        progressDialog = ProgressDialog.show(context, "Info", "Doing task...", true); 
         } 
        }); 
      dlg.setButton(AlertDialog.BUTTON_NEGATIVE, "Continue regardless", 
        new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int id) 
         { 
          dlg0Showing = false; 
          dialog.dismiss(); 
         } 
        }); 
      dlg.show(); 
      return; 
     } 
    }); 
    //wait for dialogs to have completed 
    while(dlg0Showing) 
    { 
     try{Thread.sleep(500);} 
     catch(Exception ex) {} 
    } 
    if(dlg1Showing) 
    { 
     doTask(args); 
     progressDialog.dismiss(); 
    } 
    //GC cleanup 
    progressDialog = null; 
} 
Смежные вопросы