0

我有一项从 MainActivity 开始的服务:

    Intent intent = new Intent(getBaseContext(), MyService.class);
    getBaseContext().startService(intent); 

在 MyService 中,我创建并启动一个线程,为其提供对服务上下文的引用:

    mThread = new MyThread(this);
    mThread.start();

然后在线程内部,我想显示一个 ProgressDialog。我试过这个:

           mProgressDialog = ProgressDialog.show(mContext,
             "", "Receiving file...", true);
             mProgressDialog.show();

但我得到“RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序”。这是有道理的,所以我尝试了这个:

            HandlerThread progressHandlerThread = new HandlerThread(
                    "ProgressHandlerThread");
            progressHandlerThread.start();

            Handler progressHandler = new Handler(
                    progressHandlerThread.getLooper());
            progressHandler.post(new Runnable()
            {
                @Override
                public void run()
                {
                    mProgressDialog = ProgressDialog.show(mContext, "",
                            "Receiving file...", true);
                    mProgressDialog.show();
                }
            });

但我得到“BadTokenException:无法添加窗口令牌不适用于应用程序”,但我不明白该错误的含义。

我已经看到了:从服务内的线程显示 ProgressDialog

并且结论似乎是我需要运行OnUIThread,但是由于我在服务中,因此我没有对活动的引用来执行此操作。谁能解释这个 BadTokenException 并提出一个好的方法来做到这一点?

4

3 回答 3

1
于 2013-10-08T17:09:34.083 回答
0

Not much idea about badTokenException , but I can suggest you to use AsyncTask to solve this kind of problem. You can start the progressdialog in preExecute() method and dismiss it in postExecute() method because these both are running on UI thread.

于 2013-10-08T18:08:52.923 回答
0

I just implemented this from a thread here. Please read Rachit Mishra's answer further down the page talking about a ProgressBar:

Communication between Activity and Service

I have this in my service:

public void sendMessage(int state) {
    Message message = Message.obtain();
    switch (state) {
        case 1://SHOW:
            message.arg1 = 1;
            break;
        case 0:
            message.arg1 = 0;
            break;
    }
    try {
        messageHandler.send(message);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

Call sendMessage() with 1 or 0 to show or dismiss the ProgressDialog within your service.

And this is in my Main Activity:

private ProgressDialog progress;

public class MessageHandler extends Handler {
    @Override
    public void handleMessage(Message message) {
        int state = message.arg1;
        switch (state) {
            case 0://HIDE
                progress.dismiss();
                break;
            case 1://SHOW
                progress = ProgressDialog.show(MainActivity.this, (getResources().getString(R.string.CONNECTING) + "..."), (getResources().getString(R.string.PLEASE_WAIT) + "!"));  //show a progress dialog
                break;
        }
    }
}

The ProgressDialog cannot be shown from the service, it must be called from the activity or fragment. I hope I added all the code you need and that it works well for your needs. To be honest I'm not sure how the message handler works but it works for me! The naming is probably not the best either lol. Sorry.

于 2017-06-21T03:11:54.437 回答