CalledFromWrongThreadException修改使用基于PhoneGap的活动视图 [英] CalledFromWrongThreadException modifying a view using PhoneGap based Activity
问题描述
我的Android应用程序使用基于PhoneGap的活动
登录。但用户登录后,在接下来的活动中,我在后台运行的任务。但是,当登录成功方法试图编辑视图(PhoneGap的活动被关闭后),它总是抛出
android.view.ViewRoot $ CalledFromWrongThreadException:只有创建视图层次可以触摸其观点原来的线程
块引用>我的code是:
// BeginActivity延伸DroidGap
公共类BeginLoginActivity扩展BeginActivity
{
@覆盖
保护字符串getFirstUrl(){
意向意图= getIntent();
字符串pageState = intent.getStringExtra(SplashActivity.EXTRA_PAGE_STATE); 如果(pageState == NULL){
pageState =登录;
} 返回文件:///android_asset/www/login.html#+ pageState;
} //通过JavaScript在调用的login.html
公共无效gotoMain(){
意向意图=新意图(这一点,MainNative.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(意向);
完();
}
}在MainNative课,我code,它在后台运行一个任务
公共类MainNative延伸活动{
...
公共无效loadItems(){
...
新WatchlistHelper(本).execute(getItemId());
} 公共无效setWatchedStatus(布尔_true){
//这正是WebViewCoreThread被抛出,
//每当PhoneGap的基于活动previously已经打开
//它运行良好,如果没有PhoneGap的活动已经运行
watchlistButton_.setImageResource(_true?R.drawable.native_rating_important
:R.drawable.native_rating_not_important);
watchlistButton_.setTag(_true);
watchlistButton_.setVisibility(可见);
watchlistLoading_.setVisibility(GONE);
}
...
}WatchlistHelper:
公共静态类WatchlistHelper扩展的AsyncTask<弦乐,太虚,布尔>
{
私人MainNative mContext_; ... @覆盖
保护布尔doInBackground(字符串... _ids){
//我的code,在后台运行
返回IsTrue运算;
} @覆盖
保护无效onPostExecute(布尔_isTrue){
mContext_.setWatchedStatus(_isTrue);
}
}从logcat的日志:
14 06-21:45:57.462:E / AndroidRuntime(265):致命异常:WebViewCoreThread
06-21 14:45:57.462:E / AndroidRuntime(265):$ android.view.ViewRoot CalledFromWrongThreadException:只有创建视图层次可以触摸其观点原来的线程。
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.ViewRoot.checkThread(ViewRoot.java:2802)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.ViewRoot.requestLayout(ViewRoot.java:594)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.widget.ScrollView.requestLayout(ScrollView.java:1200)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.view.View.requestLayout(View.java:8125)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.widget.ImageView.setImageResource(ImageView.java:275)
06-21 14:45:57.462:E / AndroidRuntime(265):在com.posaurus.android.elements.MainNative.setWatchedStatus(MainNative.java:160)
06-21 14:45:57.462:E / AndroidRuntime(265):在com.posaurus.android.elements.MainNative $ WatchlistHelper.onPostExecute(MainNative.java:205)
06-21 14:45:57.462:E / AndroidRuntime(265):在com.posaurus.android.elements.MainNative $ WatchlistHelper.onPostExecute(MainNative.java:1)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.os.AsyncTask.finish(AsyncTask.java:417)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.os.AsyncTask.access $ 300(AsyncTask.java:127)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.os.AsyncTask $ InternalHandler.handleMessage(AsyncTask.java:429)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.os.Handler.dispatchMessage(Handler.java:99)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.os.Looper.loop(Looper.java:123)
06-21 14:45:57.462:E / AndroidRuntime(265):在android.webkit.WebViewCore $ WebCoreThread.run(WebViewCore.java:621)
06-21 14:45:57.462:E / AndroidRuntime(265):在java.lang.Thread.run(Thread.java:1096)
解决方案请参阅的这PhoneGap的文档这里:
线程
JavaScript中的web视图没有在UI线程上运行。它运行在
在WebCore的线程。 execute方法还运行在的WebCore
主题。
块引用>问题是,
gotoMain()
正在的WebCore的线程,这意味着你要开始MainNative $运行C $ C>的WebCore的线程上活动,这是不正确。
您应该能够通过修改
gotoMain()
的方法,以确保它不会在UI线程的工作来解决这个问题:公共无效gotoMain(){
在UI线程上运行// code:
runOnUiThread(新的Runnable(){
公共无效的run(){
意向意图=新意图(BeginLoginActivity.this,MainNative.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(意向);
完();
}
});
}编辑:它也有可能是你正在运行了这个问题。在旧版本的Android(果冻豆之前),有必要确保在
的AsyncTask
类加载在主线程上。有了这样你的PhoneGap的应用程序是安装,它可能是你的code引用的AsyncTask
(强制类加载)第一次是在后台线程。如果发生这种情况,的AsyncTask
类将基本上无法使用。如果你看一下我链接到的答案,还有一行一块code,你可以把任何地方在您的应用程序:(1)早期运行;(2)你知道的主运行线程...这将code中的主线程上,然后将强制在正确的线程类加载,并解决问题。的Class.forName(android.os.AsyncTask);
My android app uses a PhoneGap-based
Activity
for login. But after the user login, in the next activity, I run a task in the background. But when the login success method is trying to edit a view (after the PhoneGap activity is closed), it always throwsandroid.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
My code is:
// BeginActivity extends DroidGap public class BeginLoginActivity extends BeginActivity { @Override protected String getFirstUrl() { Intent intent = getIntent(); String pageState = intent.getStringExtra(SplashActivity.EXTRA_PAGE_STATE); if (pageState == null) { pageState = "login"; } return "file:///android_asset/www/login.html#" +pageState; } //invoked at login.html via javascript public void gotoMain() { Intent intent = new Intent(this, MainNative.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); } }
In MainNative class, I code a task that runs in the background
public class MainNative extends Activity { ... public void loadItems() { ... new WatchlistHelper (this).execute(getItemId()); } public void setWatchedStatus(Boolean _true) { // this is where the WebViewCoreThread is thrown, // whenever a phonegap based Activity previously has been opened // and it run well if there's no phonegap Activity has run watchlistButton_.setImageResource(_true ? R.drawable.native_rating_important : R.drawable.native_rating_not_important); watchlistButton_.setTag(_true); watchlistButton_.setVisibility(VISIBLE); watchlistLoading_.setVisibility(GONE); } ... }
WatchlistHelper :
public static class WatchlistHelper extends AsyncTask<String, Void, Boolean> { private MainNative mContext_; ... @Override protected Boolean doInBackground(String... _ids) { // My code that run in background return isTrue; } @Override protected void onPostExecute(Boolean _isTrue) { mContext_.setWatchedStatus(_isTrue); } }
The logs from logcat:
06-21 14:45:57.462: E/AndroidRuntime(265): FATAL EXCEPTION: WebViewCoreThread 06-21 14:45:57.462: E/AndroidRuntime(265): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.ViewRoot.checkThread(ViewRoot.java:2802) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.ViewRoot.requestLayout(ViewRoot.java:594) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.widget.ScrollView.requestLayout(ScrollView.java:1200) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.view.View.requestLayout(View.java:8125) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.widget.ImageView.setImageResource(ImageView.java:275) 06-21 14:45:57.462: E/AndroidRuntime(265): at com.posaurus.android.elements.MainNative.setWatchedStatus(MainNative.java:160) 06-21 14:45:57.462: E/AndroidRuntime(265): at com.posaurus.android.elements.MainNative$WatchlistHelper.onPostExecute(MainNative.java:205) 06-21 14:45:57.462: E/AndroidRuntime(265): at com.posaurus.android.elements.MainNative$WatchlistHelper.onPostExecute(MainNative.java:1) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.os.AsyncTask.finish(AsyncTask.java:417) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.os.AsyncTask.access$300(AsyncTask.java:127) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.os.Handler.dispatchMessage(Handler.java:99) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.os.Looper.loop(Looper.java:123) 06-21 14:45:57.462: E/AndroidRuntime(265): at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:621) 06-21 14:45:57.462: E/AndroidRuntime(265): at java.lang.Thread.run(Thread.java:1096)
解决方案See this PhoneGap document here:
Threading
JavaScript in the WebView does not run on the UI thread. It runs on the WebCore thread. The execute method also runs on the WebCore thread.
The problem is that
gotoMain()
is being run on the WebCore thread, which means you're trying to start theMainNative
activity on the WebCore thread, which is incorrect.You should be able to fix this by modifying your
gotoMain()
method to make sure it does its work on the UI thread:public void gotoMain() { // run code on the UI thread: runOnUiThread(new Runnable() { public void run() { Intent intent = new Intent(BeginLoginActivity.this, MainNative.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); } }); }
Edit: it's also possible that you are running into this problem. In older versions of Android (before Jelly Bean), it's necessary to make sure that the
AsyncTask
class is loaded on the main thread. With the way your PhoneGap app is setup, it's possible that the first time your code referencesAsyncTask
(forcing the class to be loaded) is on a background thread. If this happens, theAsyncTask
class will essentially be unusable. If you look at the answer I link to, there is a one line piece of code that you can put anywhere in your app that (1) runs early, and (2) you know runs on the main thread ... placing this code on the main thread will then force class loading on the correct thread, and fix the problem.Class.forName("android.os.AsyncTask");
这篇关于CalledFromWrongThreadException修改使用基于PhoneGap的活动视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!