Android - 在主布局完成显示后立即运行与 UI 相关的代码
Posted
技术标签:
【中文标题】Android - 在主布局完成显示后立即运行与 UI 相关的代码【英文标题】:Android - Run UI-dependant code right after main layout has finished displaying 【发布时间】:2016-01-24 11:24:38 【问题描述】:我正在编写我的第一个 android 应用程序。我的主布局上有一个ExpandableListView
,需要一些时间来加载(~5s)。我需要在理论上显示 UI 之前或之后调用静态方法,但该方法绝对需要能够显示AlertDialog
。根据我的测试,需要在显示任何 AlertDialog 之前显示 UI,这是有道理的。
据我了解,当onResume()
返回时,应用程序会显示 UI。但是,似乎没有任何简单的方法可以在onResume()
返回之后立即在 UI 线程上执行代码,以便我可以显示AlertDialog
,而不是使用来自AsyncTask
的onPostExecute()
,它需要在之前返回它会显示我的测试中没有的任何图形对话框/Toast。
我花了很多时间尝试OnGlobalLayoutListener
、Runnable
和AsyncTask
之类的东西,但现在我意识到由于各种原因这些都不起作用,我没有想法。
编辑:代码
@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);
【问题讨论】:
5s 加载视图...我希望你没有在 UI 线程上这样做。您可以尝试在 onResume 返回之前调用 runOnUIThread 方法。 试图在onResume
中使用Handler
?
@KamenStoykov 感谢您的回复;我在onResume()
返回之前尝试了runOnUIThread
,但是在我的方法触发时UI 仍然没有显示。以后有机会我会试试Handler
。
所以使用MessageQueue#addIdleHandler
并在IdleHandler
中显示您的对话框
@pskink 我有我的IdleHandler
,但是我应该如何实例化或者我应该从哪里获取当前活动的 MessageQueue?
【参考方案1】:
我找到了解决方案;它有效,但我相信它可以做得更好/更优雅。重申目标:我需要在显示主活动的主布局之后立即运行显示对话框的代码。
这段代码的作用: 如果用户在主布局显示后立即按下AlertDialog
的肯定按钮并显示ProgressDialog
直到任务完成。
在您的工作线程中,您还可以使用static HashMap<Dialog, Boolean>
或类似的东西来轻松跟踪所有嵌入式对话框的状态(如果您有很多),但您的所有对话框都必须是static
才能工作。
在您的主 Activity 类中:
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();
在我的班级中:
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)
tryThread.sleep(500);
catch(Exception ex)
if(dlg1Showing)
doTask(args);
progressDialog.dismiss();
//GC cleanup
progressDialog = null;
【讨论】:
以上是关于Android - 在主布局完成显示后立即运行与 UI 相关的代码的主要内容,如果未能解决你的问题,请参考以下文章