为什么AsyncTask在应用程序的主线程中运行?

14

在我的应用程序中,我有一个UI类,其名称为“SettingActivity”。

然后为了在后台执行一些任务,我将这个UI类(SettingActivity)绑定到一个服务。在该服务中有两个预定义的方法(在.aidl文件中定义),一个是startTask(),另一个是stopTask()。

在startTask()内部,我调用了一个AsyncTask。但是当我检查此AsyncTask的Looper名称时,它是“main”。在我看来,AsyncTask应该启动另一个线程而不是主线程

那么,有人知道为什么会发生这种情况吗?

以下是代码:

@Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG,“onPreExecute ”+Looper.myLooper().getThread().getName());
    }

然后我将得到输出为main。


1
如果您能发布一些示例代码,那将非常有帮助。 - Jon Skeet
2个回答

27

AsyncTask有几个部分可以重写:一个doInBackground方法实际上在单独的线程上运行,还有三个方法- onPreExecuteonProgressUpdateonPostExecute - 运行在UI线程上。(这些方法的默认实现什么都不做,只有在您从doInBackground中调用publishProgress时才会执行onProgressUpdate。)onPostExecute的目的是发布结果(例如更新视图层次结构或在文本视图中设置文本),必须在UI线程上完成。它还可以发布进度更新。为了使所有这些正常工作,必须在UI线程上创建AsyncTask,并调用execute方法。

您不能从doInBackground中调用UI操作-这样做会导致应用程序崩溃。


例如,如果我想在单独的线程上制作Toast,我应该怎么做? - Behzad
1
@Behzad - 如果您有活动的引用,可以按照这个答案所述使用runOnUiThread - Ted Hopp
@TedHopp - +1。它并没有真正地分离线程!我的意思是,如果我运行一个分离的线程,并在其中运行一个更新UI的函数(使用runOnUitThread),它会进入UI线程池并在队列中运行。我是对的吗?我想同时做一些其他事情(都是更新UI),比如弹出一个toast。这可能吗? - Behzad
@Behzad - 如果您正在运行一个工作线程并将Runnable传递给runOnUiThread,那么Runnable将在将来的某个时间(通常很快)排队在UI线程上运行,并且对runOnUiThread的调用将立即返回。然后,您可以继续在工作线程中做其他事情(包括其他对runOnUiThread的调用),无论UI线程是否执行了您传递为参数的任何Runnables - Ted Hopp
@GokhanArik - 没有看到你的代码,很难知道发生了什么。你是如何确定doInBackground()在UI线程上运行的? - Ted Hopp
显示剩余4条评论

10

事实上,我已经查阅了Android文档,其中onPreExecute()、onProgressUpdate(Progress...)和onPostExecute(Result)都是“在UI线程上调用”的。

只有doInBackground(Params...)方法是“在后台线程上调用的”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接