引用来自here的AsyncTask文档,它说
- 必须在UI线程上加载AsyncTask类。这个完成了 自JELLY_BEAN起。
- 必须创建任务实例 UI线程。
必须在UI线程上调用execute(Params...)
。- 请 不要拨打
onPreExecute()
,onPostExecute(Result)
,doInBackground(Params...)
,onProgressUpdate(Progress...)
手动。
现在在UI线程上创建AsyncTask引用的原因是什么?这是Looper的问题吗?
答案 0 :(得分:2)
我认为这样做是为了确保在UI线程上初始化Handler,因此在处理程序的构造函数中,myLooper()将返回mainUIThreadLooper,稍后发送的消息将稀释到UI线程。
public abstract class AsyncTask<Params, Progress, Result> {
private static final InternalHandler sHandler = new InternalHandler();
....
}
和
public Handler() {
...
mLooper = Looper.myLooper();
...
}
答案 1 :(得分:1)
我认为在其他地方创建AsyncTask是没有意义的,因为AsyncTask专门用于在UI线程上做一些准备,然后在另一个线程中执行某些操作,然后再次在UI线程中发布任何结果。
答案 2 :(得分:0)
请检查this answer。
必须在UI线程上加载AsyncTask.class,因为它具有 static fied引用处理程序:
private static final InternalHandler sHandler = new InternalHandler();
因此,如果您第一次在另一个带有looper( NonMainThred )的线程上运行 AsynckTask ,那么AsuncTask上的 ANY 实例将发布它是onPostExecute(和其他)方法,用于特定的 NonMainThread no metter,您将尝试从中启动AsyncTask。
如果现在你尝试处理来自onPostExecute的任何android-UI元素,它将崩溃并出现以下错误:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.