2012-05-22 30 views
1

即使我將它拋入AsyncTask的DoInBackground方法中,我也會收到一個CalledFromWrongThreadException異常!誰能告訴我爲什麼以及如何解決它?從AsyncTask錯誤的線程異常中調用

/** 
    * Recognizes key words in responseTexts and runs the appropriate function 
    * @param responseText 
    */ 
    private void responseHandler(String responseText) { 
     if(responseText.startsWith("Notes", 0)) { 
      notes.add(responseText); 
      new DownloadFilesTask().execute("WriteInternal" , null, null); 
     } 
    } 

這是我的AsyncTask類

private class DownloadFilesTask extends AsyncTask<String, Void, String> { 
    protected String doInBackground(String... command) { 
    if(command[0].equals("WriteInternal") { 
     //write to internal storage 
    FileOutputStream fOut = null; 
    OutputStreamWriter osw = null; 
    try{ 
     fOut = openFileOutput("notes.txt", Context.MODE_PRIVATE); 
     osw = new OutputStreamWriter(fOut); 
     for (int i = 0; i < notes.size(); i++){ 
      osw.write(notes.get(i) + "\n"); 
     } 
     osw.close(); 
     fOut.close(); 
    } catch(Exception e) { 
     e.printStackTrace(System.err); 
    } 

    notesListView.setAdapter(arrayAdapter); //refreshes the listView 

     } 
else { 
     sendCommand(command[0]); 
     return null; 
} 
    } 

    protected void onProgressUpdate(Void... progress) {} 
    protected void onPostExecute(String result) {} 
} 

這裏是我得到的堆棧跟蹤:

05-22 15:14:20.370: E/AndroidRuntime(11730): FATAL EXCEPTION: AsyncTask #2 
05-22 15:14:20.370: E/AndroidRuntime(11730): java.lang.RuntimeException: An error occured while executing doInBackground() 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.os.AsyncTask$3.done(AsyncTask.java:278) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.lang.Thread.run(Thread.java:856) 
05-22 15:14:20.370: E/AndroidRuntime(11730): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:722) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:771) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4005) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.View.invalidate(View.java:8576) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.view.View.invalidate(View.java:8527) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.widget.AbsListView.resetList(AbsListView.java:1734) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.widget.ListView.resetList(ListView.java:502) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.widget.ListView.setAdapter(ListView.java:442) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at com.nelson.jarvisclientics.Notes$DownloadFilesTask.doInBackground(Notes.java:281) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at com.nelson.jarvisclientics.Notes$DownloadFilesTask.doInBackground(Notes.java:1) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at android.os.AsyncTask$2.call(AsyncTask.java:264) 
05-22 15:14:20.370: E/AndroidRuntime(11730): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
05-22 15:14:20.370: E/AndroidRuntime(11730): ... 5 more 
+0

發佈從運行此代碼收到的堆棧跟蹤也會很有幫助。 – ky1enamic

回答

5

嘗試用runOnUIThread(new Runnable{/*code goes here*/}())

+0

只需要注意一下:使用Android的設計原則,可能會更好,更多,就像其他人在onPostExecute()中所說的那樣處理這個問題。只需緩存你的文件,然後實際寫入onPostExecute()。 – Codeman

+0

你不應該在ui線程上進行文件訪問。 notesListView.setAdapter(arrayAdapter)必須在ui Thread上完成。但是在AsyncTask中,您可以在ui線程上執行的onPostExecute()中執行此操作。 –

+0

@DirkJäckel好點,我添加了一條評論暗示。 – Codeman

1

包裹你的文件訪問代碼,你可以使用onPostExecute它運行在UI線程上......這是使用asynctask的基礎。

+0

我在上面的解決方案中添加了一條評論,表明這是更好的方法。 – Codeman

2

您得到此異常的原因是因爲您正嘗試更新AsyncTask的doInBackground()方法中的UI。當您在此處爲您的列表視圖設置適配器時發生這種情況:notesListView.setAdapter(arrayAdapter); //refreshes the listView

您應該將其移至onPostExecute。在onPostExecute中更新UI並在必要時顯示任何錯誤消息。

另外請注意,你在後臺調用handleCommand();確保這不會更新UI!

相關問題