4

我有一个带有复选框的列表视图。对于每个复选框(大约 3 个),它都有一个特定的 AsyncTask 。

我永远不知道用户选择了哪些复选框,因此我无法将 AlertDialog 放在异步任务的末尾,因为我永远不知道用户是只选择了一个复选框,还是两个或三个。

因为 AsyncTask 是分步执行的(只有当第一个 Async 完成时,第二个才开始),所以我考虑在所有内容的末尾添加一个带有 AlertDialog 的新 AsyncTask。

private class showMessageAsync extends AsyncTask<Void, Integer, String> {
    @Override
    protected String doInBackground(Void... params){
        AlertDialog alertDialog;
        alertDialog = new AlertDialog.Builder(getApplicationContext).create();
        alertDialog.setTitle("The Process");  
        alertDialog.setIcon(R.drawable.success);
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.setMessage("All done!");  
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                              new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent A = new Intent(DownloadActivity.this, Menu_activity.class);
                startActivity(A);
                finish();
            }
        });
        alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {          
            @Override
            public void onDismiss(DialogInterface dialog) {
                Intent A = new Intent(DownloadActivity.this, Menu_activity.class);
                startActivity(A);
                finish();
            }
        });
        alertDialog.show();
        return "Executed";
    }
}

这是错误:

10-21 04:24:34.117: E/AndroidRuntime(1026): FATAL EXCEPTION: AsyncTask
#4 10-21 04:24:34.117: E/AndroidRuntime(1026): java.lang.RuntimeException: An error occured while executing
doInBackground() 10-21 04:24:34.117: E/AndroidRuntime(1026):    at
android.os.AsyncTask$3.done(AsyncTask.java:299) 10-21 04:24:34.117:
E/AndroidRuntime(1026):     at
java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
java.util.concurrent.FutureTask.run(FutureTask.java:239) 10-21
04:24:34.117: E/AndroidRuntime(1026):   at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 10-21
04:24:34.117: E/AndroidRuntime(1026):   at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
java.lang.Thread.run(Thread.java:841) 10-21 04:24:34.117:
E/AndroidRuntime(1026): Caused by: java.lang.RuntimeException: Can't
create handler inside thread that has not called Looper.prepare()
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
android.os.Handler.<init>(Handler.java:197) 10-21 04:24:34.117:
E/AndroidRuntime(1026):     at
android.os.Handler.<init>(Handler.java:111) 10-21 04:24:34.117:
E/AndroidRuntime(1026):     at android.app.Dialog.<init>(Dialog.java:107)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at
android.app.AlertDialog.<init>(AlertDialog.java:114) 10-21
04:24:34.117: E/AndroidRuntime(1026):   at
android.app.AlertDialog$Builder.create(AlertDialog.java:931) 10-21
04:24:34.117: E/AndroidRuntime(1026):   at com.example.MyExample.DownloadActivity$showMessageAsync.doInBackground(DownloadActivity.java:487)
10-21 04:24:34.117: E/AndroidRuntime(1026): at com.example.MyExample.DownloadActivity$showMessageAsync.doInBackground(DownloadActivity.java:1)
10-21 04:24:34.117: E/AndroidRuntime(1026):     at android.os.AsyncTask$2.call(AsyncTask.java:287) 10-21 04:24:34.117:
E/AndroidRuntime(1026):     at java.util.concurrent.FutureTask.run(FutureTask.java:234) 10-21
04:24:34.117: E/AndroidRuntime(1026):   ... 4 more

我这样称呼我的 AsyncTask :

if(list.get(0).isSelected() == true){
    // list = class that contains checkboxs state
    String[] params = {order, String.valueOf(limit_customers) };
    customers.execute(params);
}
if(list.get(1).isSelected() == true){
    String[] params = {order, String.valueOf(limit_products) };
    products.execute(params);
}
// etc, and in the end of this:
showMessageAsync sM = new showMessageAsync();
sM.execute();

错误在这一行:

alertDialog = new AlertDialog.Builder(getApplicationContext()).create();
4

4 回答 4

23

警报对话框是前台的东西,所以它不能在异步任务的后台方法中完成。这样做

private class showMessageAsync extends AsyncTask<String, Void, String> {
     AlertDialog alertDialog;
     protected void onPreExecute() {
    super.onPreExecute();
            alertDialog = new AlertDialog.Builder(YourClasss.this);  
     }
     @Override
     protected String doInBackground(Void... params){       
            return null;
     }
     @Override
     protected void onPostExecute(String result) {
            super.onPostExecute(result);

            alertDialog.setTitle("The Process");  
            alertDialog.setIcon(R.drawable.success);
            alertDialog.setCanceledOnTouchOutside(false);
            alertDialog.setMessage("All done!");  
            alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                                  new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                                Intent A = new Intent(DownloadActivity.this, Menu_activity.class);
                                                startActivity(A);
                                                finish();
                                        }
                                    });
            alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {          
                                  @Override
                                  public void onDismiss(DialogInterface dialog) {
                                            Intent A = new Intent(DownloadActivity.this, Menu_activity.class);
                                            startActivity(A);
                                            finish();
                                  }
                    });
            alertDialog.show();
    }

}
于 2013-10-21T08:59:43.327 回答
4

原因:java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序

您正试图在里面显示一个 lertdialog doInbackgrounddoInbackground在后台线程上调用。并且 ui 应该在 ui 线程上更新。

您可以在中返回后台计算的结果并在中doInbackground更新 ui onPostExecute。或者使用runOnUiThreadwhich 是活动类的方法。或显示对话框onProgressUpdate(Progress...)

http://developer.android.com/reference/android/os/AsyncTask.html

还要查看@http://developer.android.com/guide/components/processes-and-threads.html 下Threads主题

当应用程序启动时,系统会为应用程序创建一个执行线程,称为“main”。这个线程非常重要,因为它负责将事件分派给适当的用户界面小部件,包括绘图事件。它也是您的应用程序与 Android UI 工具包中的组件(来自 android.widget 和 android.view 包的组件)交互的线程。因此,主线程有时也称为 UI 线程。

也使用活动上下文

  alertDialog = new AlertDialog.Builder(ActivityContext).create();
于 2013-10-21T08:39:25.907 回答
3

您不能在 do inbackground method.same 中调用警报框。在 doinbg 方法中不能执行任何 UI 操作。而是使用 post execute 方法,或者改变必须做的事情的方式。

于 2013-10-21T08:38:45.973 回答
1

您可以通过函数 doInBackground... 中的此方法访问 ui...:

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        if (!dialog.isShowing()) {
            dialog.show();
        }
        dialog.setMessage(getText(R.string.lbl_downloading) + " : " + String.valueOf(mCount) + " / " + String.valueOf(totalItems));
    }
});

这是从我的代码中截取的片段,它显示了下载的项目。

于 2016-04-16T22:15:55.253 回答