Android - 在主布局完成显示后立即运行与 UI 相关的代码

标签 android android-layout android-asynctask

我正在编写我的第一个 Android 应用程序。我有一个 ExpandableListView在我的主要布局上需要一些时间来加载(~5 秒)。理论上我需要在显示 UI 之前或之后调用静态方法,但该方法绝对需要能够显示 AlertDialog。 .根据我的测试,UI 需要在显示任何 AlertDialog 之前显示,这是有道理的。

据我了解,应用程序在 onResume() 时显示 UI返回。但是,似乎没有任何简单的方法可以在 onResume() 之后立即在 UI 线程上执行代码。返回以便我可以显示 AlertDialog除了使用 onPostExecute()来自 AsyncTask ,它需要在显示我的测试中的任何图形对话框/Toast 之前返回,这是我不能拥有的。

我花了很多时间尝试像 OnGlobalLayoutListener 这样的事情, RunnableAsyncTask ,但我现在意识到,由于各种原因,这些都不起作用,而且我没有想法。

编辑:代码

@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);
}

最佳答案

我找到了解决方案;它有效,但我相信它可以做得更好/更优雅。重申一下目标:我需要在显示主要 Activity 的主要布局后立即运行显示对话框的代码。

此代码的作用:此代码允许您执行 MyClass.doTask(args)如果用户按下 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();
    }
}

在我的类(class)中:

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;
}

关于Android - 在主布局完成显示后立即运行与 UI 相关的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33327504/

相关文章:

android - 异步任务执行 doInBackground() 时发生错误

java - 带接口(interface)的 AsyncTask onPostExecute

android - Kotlin:将函数中的对象作为引用传递并更改其实例

android - 如果仅安装了面部作为生物特征,则使用 AndroidX.Biometric 的 KeyGeneration 会失败

java - R.layout.main 无法解析

android - 在android中开发对角线布局

android - 无法修复 AsyncTask 崩溃 : PendingIntent or SSL connection or other causes?

android - 出现键盘时滚动布局

android - WebView 在加载进度条时显示为白色

Android FrameLayouts 并排与独立的内部滚动