2015-01-31 66 views
0

我已经调用了一个Activity从一个片段更新UI的方法,我得到一个无声的CalledFromWrongThreadException告诉我Only the original thread that created a view hierarchy can touch its views从UI线程运行的Fragment中调用Activity方法吗?

我的活动:

@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

请显示源代码如何从片段调用updateLayout方法 – 2015-01-31 20:35:10

+0

我已更新问题。 – 2015-01-31 20:42:02

+0

片段中的哪个方法执行updateLayout()仍然没有信息。请显示您的片段的更多代码 – 2015-01-31 20:44:50

回答

2

碎片和活动都在主UI线程上运行。你的问题是你从一个JS线程调用你的updateLayout()方法,这不是你的UI线程。既然你不能修改除主UI线程以外的任何其他线程的UI组件,你将会得到这个异常。

解决方法:就像你说的,使用runOnUiThread。

+0

用户界面更新最近可能会运行。就像我称之为代码或强制用户界面更新而没有延迟一样,有没有办法运行这些代码? – 2015-02-01 05:14:13

+1

UI线程正在不断运行。它不取决于是否需要刷新任何UI组件。因此,你的代码在被调用后会立即运行。如果你确实需要强制UI更新 - 这对你的情况不需要 - 你可以在你的一个活动UI组件上使用invalidate()方法,如:View v = findViewById(R.id.some_id); v.invalidate(); – Kasra 2015-02-01 06:27:59

相关问题