標籤:ict 運行 edm exception class only example art col
最近自己再寫一個小項目練手,建立一個線程從網路擷取資料然後顯示在 recyclerView 上。寫好後發現頁面能夠顯示,但是有時候會把請求的資料顯示過來,有時候不會。點開 android monitor 一看,有一個提示 :
Only the original thread that created a view hierarchy can touch its views.
異常的意思是說只有建立這個view的線程才能操作這個 view,普通會認為是將view建立在非UI線程中才會出現這個錯誤。
本來我想將就下,能看到算了的,說明我會簡單使用 fragment 了。不過作為程式員我們肯定要尋根問底的啊。
這段請求資料代碼如下所示:
new Thread(new Runnable() { @Override public void run() { try { String url = ""; OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).method("GET", null).build(); okhttp3.Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String responseString = (response.body() == null ? "" : response.body().string()); ......解析資料 WidgetActionEvent event = new WidgetActionEvent(WidgetActionEvent.ACTION_CLICK); event.object = feedModel; EventBus.getDefault().post(event); //iLoadData.loadData(feedModel); } else { Log.i(TAG, "okHttp is request error"); } } catch (IOException e) { e.printStackTrace(); } } }).start();
資料請求之後,解析,並採用 eventbus 來傳送資料。
ps :如果你是在 mainActivity 中調用上述代碼,是不會產生的異常的,因為都是運行在主線程中。
變形一 : 崩潰
於是我換了一種形式來傳遞資料,這次採用回調的方式,也就是上面被注釋掉的那行代碼:
iLoadData.loadData(feedModel);
這次不用 eventbus 竟然崩潰了......我能怎麼辦,我也很無奈啊。
FATAL EXCEPTION: Thread-932Process: example.hope.mvpwithrecyclerview, PID: 4916android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
解決辦法:採用 handle
實現代碼如下:
/** * 發起網路請求 */ public static void okHttp_synchronousGet(final Handler handler) { new Thread(new Runnable() { @Override public void run() { try { String url = "http://eff.baidu.com:8086/action/combined/action_RetData.php?name=shenjiaqi"; OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).method("GET", null).build(); okhttp3.Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String responseString = (response.body() == null ? "" : response.body().string()); ......解析資料 handler.sendMessage(handler.obtainMessage(22, feedModel)); } else { Log.i(TAG, "okHttp is request error"); } } catch (IOException e) { e.printStackTrace(); } } }).start(); }
然後再 fragment 添加下面代碼用來處理傳過來的資料:
/** * 接收解析後傳過來的資料 */ Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Object model = (Object) msg.obj; showPictures(model); } };
這樣就能後完美的解決這個問題了。
Android: Only the original thread that created a view hierarchy can touch its views 異常