Android AsyncTask cannot resolve CalledFromWrongThreadException问题解决方案
来源:互联网 发布:vb精简版6.0怎么安装 编辑:程序博客网 时间:2024/06/07 13:55
Android 在JELLY_BEAN之前的版本调用AsyncTask时,如果首次不是在主线程加载,可能会报如下错误:cannot resolve CalledFromWrongThreadException。可参考如下Stackoverflow中介绍的解决方法:
----------------------------------------------------
From: http://stackoverflow.com/questions/18478347/android-runonuithread-asynctask-cannot-resolve-calledfromwrongthreadexception/18479289#18479289
-----
I'm working for an Android app and implementing a ProgressBar by using AsyncTask class.
The problem is that on some devices, it causes "CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views." in onPostExecute. On those devices, the problem occurs 100%. On other devices, it works fine.
Starting the AsyncTask
From the Android Docs
Threading rules
There are a few threading rules that must be followed for this class to work properly:
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
- The task instance must be created on the UI thread.
- execute(Params...) must be invoked on the UI thread.
- Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
- The task can be executed only once (an exception will be thrown if a second execution is attempted.)
You don't show where you normally instantiate, and execute the task, so make sure that you do this in code that's already on the UI/main thread. Note that the first bullet point above might explain why this works for you on some devices, and not on others.
Creating the View Hierarchy
The message tells you
Only the original thread that created a view hierarchy can touch its views.
and you're assuming that this is because your async task is (strangely) trying to modify the UI on a background thread. However, it is possible that you get this error because the async task modifies the UI on the main thread, but the UI (ProgressBar
) was not created correctly in the first place.
See this question for an example of how you can erroneously create the view on the wrong thread (anything other than the main thread), and get this same error.
More
I would, however, like to see exactly where you are logging the thread ID, and what value(s) you're getting. If you check out my first two suggestions, and they don't solve your problem, then we may need more information.
You also mention a Handler (?), but don't show how or where you use that. Normally, using AsyncTask
removes the need to use Handler
, so I'm a little worried about how you might be using that.
Update
Per the discussion in comments below, it looks like the issue here is the one discussed in this question. Some code, probably running on a background thread, is first to cause the AsyncTask
class to be loaded. The original (pre-Jelly Bean) implementation of AsyncTask
required class loading to occur on the main thread (as mentioned in the Threading Rules above). The simple workaround is to add code on the main thread (e.g. in Application#onCreate()
) that forces early, deterministic class loading of AsyncTask
:
Class.forName("android.os.AsyncTask");
----------------------------------------------------From: http://stackoverflow.com/questions/14978924/what-is-the-difference-between-loading-and-creating-asynctask-on-the-ui-thread/18501792#18501792
-----
While reading AsyncTask documentation, the part on Threading rules, I found this:
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
- The task instance must be created on the UI thread.
- execute(Params...) must be invoked on the UI thread.
What is meant by "loading"? It's not instantiating or executing, as the documentation talked about those later.
I don't believe that this answer is actually correct.
It wouldn't make sense for the documentation to separately list instantiation and loading, if those things were actually the same. I believe this statement
The AsyncTask class must be loaded on the UI thread.
is referring to Java Class Loading. In other words, the AsyncTask
class itself needs to be loaded on the main thread. In Jelly Bean (or later), this is automatic. But, in older versions of Android, there is the potential for this class to be loaded on another thread, which can cause problems.
See this Google discussion for more information. Basically, there are conditions (for example, code using IntentService
) that can cause the AsyncTask
to be first loaded on the wrong (non-main) thread.
The simplest fix for this, prior to Jelly Bean, seems to be to use something like:
Class.forName("android.os.AsyncTask");
in the Application's onCreate() method, to force class loading to happen when you want it to.
Creating the AsyncTask
instance is probably what you think it is ... instantiating it:
MyAsyncTask task = new MyAsyncTask();
and that should also be run on the main thread.
- Android AsyncTask cannot resolve CalledFromWrongThreadException问题解决方案
- intellij cannot resolve method问题解决
- Android:CalledFromWrongThreadException
- Android Studio --“Cannot resolve symbol”
- Android:Cannot resolve symbol’R’
- Android Studio --“Cannot resolve symbol”
- android Cannot resolve symbol'R'
- cannot open clipboard问题解决方案
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
- Android Studio :cannot resolve symbol R
- android studio Cannot resolve symbol 'R'
- android studio cannot resolve symbol R
- cannot resolve symbol r android studio
- ANDROID STUDIO “CANNOT RESOLVE SYMBOL” 解决办法
- android studio 的 cannot resolve symbol R
- Android Studio “Cannot resolve symbol xxx” 解决办法
- android音频播放
- xUtils系列之DbUtils-Check注解
- Unity3d热更新(四):压缩文件
- day20/SequenceInputStream.java
- Android 上传文件,图片。以及服务器端接收相关。
- Android AsyncTask cannot resolve CalledFromWrongThreadException问题解决方案
- day20/SplitFile.java
- 家用电脑安装多系统
- &与&&的区别
- JavaScript学习笔记之Array类型与String类型
- xUtils系列之DbUtils-Column注解
- securecrt vim 颜色高亮问题
- inside sql server 2008 - logical query processing
- Linux下移动virtualbox虚拟硬盘丢失eth0