Android:无法在未调用Looper.prepare()的线程内创建处理程序

时间:2013-12-17 08:54:07

标签: android android-service progressdialog android-looper

在我的应用程序中,我有一个sercice类,它有这个方法在执行某些操作时显示进度对话框:

private void openprogresdialog() {

new AsyncTask<Integer, Integer, Boolean>()
{
    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute()
    {
        progressDialog = ProgressDialog.show(thisActivity, "Dialog","Loading...");
    }

    @Override
    protected Boolean doInBackground(Integer... params)
    {
        if (params == null)
        {
            return false;
        }
        try
        {
            Thread.sleep(params[0]);
        }
        catch (Exception e)
        {
            Log.e("tag", e.getMessage());
            return false;
        }

        return true;
    }

    @Override
    protected void onPostExecute(Boolean result)
    {
        progressDialog.dismiss();
        AlertDialog.Builder b = new AlertDialog.Builder(thisActivity);
        b.setTitle(android.R.string.dialog_alert_title);
        if (result)
        {
            b.setMessage("Download succeeded");
        }
        else
        {
            b.setMessage("Download failed");
        }
        b.setPositiveButton(getString(android.R.string.ok),
                new DialogInterface.OnClickListener()
                {

                    @Override
                    public void onClick(DialogInterface dlg, int arg1)
                    {
                        dlg.dismiss();
                    }
                });
        b.create().show();
    }
}.execute(2000);

new Thread()
{
    @Override
    public void run()
    {

        DialogInterface progressDialog = null;
        progressDialog.dismiss();
    }
}.start();
}

我希望在应用程序执行时会显示工作进度对话框但是当我运行应用程序时出现此错误:

无法在未调用Looper.prepare()

的线程内创建处理程序

我该如何解决?

编辑:

public class MyService extends Service {
    private static final String TAG = "MyService";
    Thread readthread;
    final MyService thisActivity = this;
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        final ParentActivityData data = intent.getParcelableExtra("DATA");

        readthread = new Thread(new Runnable() {
            public void run() {
                // SOME CODE TO EXECUTE //
                }
                openprogresdialog();
            }
        });

        readthread.start();

        Log.d(TAG, "onCreate");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
    }

    @Override
    public void onDestroy() {

    }
}

5 个答案:

答案 0 :(得分:1)

虽然添加Looper.prepare()可能是一个有效的选项,但如果可以的话,我宁愿添加使用Activity#runOnUIThread。另外,为什么你还在使用线程呢?

这里没有必要使用线程。

顺便说一下:你的代码

DialogInterface progressDialog = null;
progressDialog.dismiss();

将产生NullpointerException ...

答案 1 :(得分:1)

你有

readthread = new Thread(new Runnable() {
            public void run() {

在线程的运行方法中你是

openprogresdialog();

openprogresdialog中,你有一个Asynctask和一个线程。

必须在ui线程上加载Asynctask。请查看以下链接中的“线程规则”主题。

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

Can't create handler inside thread that has not called Looper.prepare()

您无法在后台线程中更新ui。 Ui应该在ui线程上更新。你的Asynctask看起来很好,但必须加载到ui线程上。

同时删除下面没用的东西。由于NullPointerException未初始化,并且您在初始化之前调用progressDialog,因此也会给dismiss

new Thread()
{
    @Override
    public void run()
    {

        DialogInterface progressDialog = null;
        progressDialog.dismiss(); // even if initialized cannot update ui in a thread
    }
}.start();

答案 2 :(得分:0)

只需在帖子的开头添加Looper.prepare();

new Thread()
    {
        @Override
        public void run()
        {
            Looper.prepare();
            DialogInterface progressDialog = null;
            progressDialog.dismiss();
        }
    }.start();

答案 3 :(得分:0)

您应该在主UI线程中执行UI调用。如果您在其他线程中执行操作,则会出现此错误。由于您从新的Thread()调用progressDialog.dismiss,因此收到此错误消息。

答案 4 :(得分:0)

new Thread()
    {
        @Override
        public void run()
        {
            Looper.prepare();

            //Your Dialog goes here

            Looper.loop(); 
        }
    }.start();

HTH。