我调用了一个从Fragment更新UI的Activity方法,然后我得到一个告诉我CalledFromWrongThreadException
的无声Only the original thread that created a view hierarchy can touch its views
。
我的活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
createDynamicView();
}
public void createDynamicView() {
// Create some View and attach that to a ViewGroup dynamically as below:
RelativeLayout rl = new RelativeLayout(this);
// ...
TextView textView = new TextView(this);
// ...
rl.addView(textView, layout_params1);
layout.addView(rl, layout_params2);
}
// Method called from Fragment
@Override
public void updateLayout() {
View v = layout.getChaildAt(index); // v is a TextView
// This line throws a silent Exception:
// android.view.ViewRootImpl$CalledFromWrongThreadException:
// Only the original thread that created a view hierarchy can touch its views
v.setBackgroundColor(Color.WHITE);
}
内部片段:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
parent = (SettingsInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement SettingsInterface");
}
}
public void updateLayout() {
parent.updateLayout();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
webView = (WebView) view.findViewById(R.id.webView1);
// ...
textWebView.addJavascriptInterface(new JSInterface(getActivity()), "Android");
}
public class JSInterface {
@JavascriptInterface
public void updateLayout() {
updateLayout();
}
}
如果我将该行放在runOnUiThread
块中,如下所示:
runOnUiThread(new Runnable() {
@Override
public void run() {
v.setBackgroundColor(Color.WHITE);
}
});
我不会得到异常,但这可能会在第一次UI更新后运行。 我想知道片段是否在一个单独的线程中运行而不是UI线程? 为什么这个例外是沉默的?
答案 0 :(得分:2)
片段和活动都在主UI线程上运行。你的问题是你从一个不是你的UI线程的JS线程调用你的updateLayout()方法。由于您无法从主UI线程以外的任何其他线程修改UI组件,因此您将获得该异常。
解决方案:就像你说的那样,使用runOnUiThread。