【问题标题】:Android method that shows ProgressDialog, runs worker and waits for worker finish显示 ProgressDialog、运行 worker 并等待 worker 完成的 Android 方法
【发布时间】:2013-04-05 07:33:15
【问题描述】:

我需要编写显示 ProgressDialog 的静态方法,在线程中运行 worker 并且在 worker 完成后 ProgreesDialog 必须关闭并且我的方法返回 worker 所做的。 这是我的代码:

public static TOut execute(final Context c, final String title, final String message, final IProgressWorker worker, final TIn param)
{

        最终 ValueHolder 结果 = 新 ValueHolder();
        最终 ProgressDialog 进度=新 ProgressDialog(c,R.layout.progress_impl_layout);
        线程主 = 新线程(新可运行(){
            @覆盖
            公共无效运行(){
                Looper.prepare();//创建新的Looper以立即显示progressDialog
                最终 Looper looper=Looper.myLooper();
                AsyncTask async = new AsyncTask(){
                    @覆盖
                    受保护的无效onPostExecute(布尔结果){
                        super.onPostExecute(结果);
                        完成=真;
                        looper.quit();//退出 Looper.loop
                        progress.dismiss();
                    }
                    @覆盖
                    受保护的无效onPreExecute(){
                        super.onPreExecute();
                        progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                        progress.setTitle(title);
                        进度.setMessage(消息);
                        进度.show();
                    }

                    @覆盖
                    受保护的布尔doInBackground(整数...参数){
                        IProgressImpl progressImpl=new MyProgressImpl(progress);
                        worker.execute(progressImpl, param);
                        返回真;
                    }
                };

                async.execute(0);
                如果(!完成){
                    Looper.loop();//立即显示progressDialog
                }
            }
        });
        main.start();
        尝试 {
            main.join();
        } 捕捉(InterruptedException e){
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        返回结果。值;
    }

一切正常,但 ProgressDialog 不会关闭。我怀疑 looper.quit() 做错了什么,但我需要停止 Looper.loop()。我调用 loop() 因为我需要立即显示 ProgressDialog。

【问题讨论】:

    标签: android progressdialog looper


    【解决方案1】:

    如何在 AsyncTask 中更新 Android UI

    建议您使用Activity.runOnUiThread() 来更新ProgressDialog 方法的UI,而不是在Looper 中使用Looper,例如show()dismiss()

    示例

    runOnUiThread(new Runnable() {
        @Override
            public void run() {
            progress.dismiss();       
        }
    });
    

    如果上面的Context cActivity 上下文,则可以使用它来访问runOnUiThread()

        c.runOnUiThread()...
    

    您可能必须通过各种方法为您的处理类提供Activity,例如将其传递到您的execute() 方法或使用Android Application 实例。

    否则,您可以使用常规的Context,但上面相同的Runnable 必须在线程或任务中执行。

    【讨论】:

    • 但我无权访问活动,因此无法调用 runOnUiThread。您不能从上下文调用 runOnUiThread()(不能更改方法参数)
    • 重要的部分是从AsyncTask方法中获取UI更新方法(即show()dismiss())。有很多方法可以做到这一点。上面的Runnable 是有效的,但你必须在Handler 中使用它而不是runOnUiThread。您也可以发布或广播 - 有很多方法可以给这只猫剥皮。
    【解决方案2】:

    首先,存储在main 变量中的线程不是主(又名UI)线程。

    至于runOnUIThread(),你可以在UI线程上创建一个Handler,post(Runnable r)postDelayed(Runnable r, long delayMillis)将替换runOnUIThread()。 [或者,您的函数已经有一个 Context 参数;你可以要求它是一个活动。]

    另请注意,在 Android 2 中,在 UI 线程以外的线程上初始化 AsyncTask 类会导致错误。

    最后,如果您使用 AsyncTask,为什么需要一个单独的线程?或者,如果您已经有一个工作线程,为什么要使用 AsyncTask?你绝对不需要他们两个。

    【讨论】:

    • Worker 不是线程。它只是有方法的类。我创建线程来拥有新的 Looper(不是主 Looper)。线程等待 asynctask(直到 looper.quit())。我会尝试使用 Handler。
    • 主要问题是我的方法需要等到工人完成。来自 Handler 的所有方法(如 post)都将 Runnable 添加到消息队列中。这不起作用,因为 Looper.loop 在我的方法之后被调用。即使我尝试 activity.runOnUiThread();刚开始我的方法是行不通的。
    猜你喜欢
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多