Android 使用AsyncTask从错误的线程异常调用

Android 使用AsyncTask从错误的线程异常调用,android,android-asynctask,asyncsocket,thread-exceptions,Android,Android Asynctask,Asyncsocket,Thread Exceptions,即使我将CalledFromErrorThreadException抛出到AsyncTask的DoInBackground方法中,我仍然会得到一个CalledFromErrorThreadException!谁能告诉我为什么以及如何修复它 /** * Recognizes key words in responseTexts and runs the appropriate function * @param responseText */ private

即使我将CalledFromErrorThreadException抛出到AsyncTask的DoInBackground方法中,我仍然会得到一个CalledFromErrorThreadException!谁能告诉我为什么以及如何修复它

/**
     * 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) {}
}

尝试使用
rununuithread包装您的文件访问代码(新的Runnable{/*代码在这里*/}())

尝试使用
rununuithread包装您的文件访问代码(新的Runnable{/*代码在这里*/}())

您可以使用在UI线程上运行的onPostExecute。。。这是使用asynctask的基础。

您可以使用在UI线程上运行的onPostExecute。。。这是使用asynctask的基础。

出现此异常的原因是您正在尝试更新asynctask的doInBackground()方法中的UI。在此处设置listview的适配器时会发生这种情况:
notesListView.setAdapter(arrayAdapter)//刷新列表视图

您应该将其移动到onPostExecute。如有必要,更新onPostExecute中的UI并显示任何错误消息


还要注意,您也在后台调用handleCommand();确保这不会同时更新UI

出现此异常的原因是您正在尝试更新AsyncTask的doInBackground()方法中的UI。在此处设置listview的适配器时会发生这种情况:
notesListView.setAdapter(arrayAdapter)//刷新列表视图

您应该将其移动到onPostExecute。如有必要,更新onPostExecute中的UI并显示任何错误消息


还要注意,您也在后台调用handleCommand();确保这不会同时更新UI

发布您从运行此代码中收到的堆栈跟踪也会很有帮助。发布您从运行此代码中收到的堆栈跟踪也会很有帮助。请注意:按照其他人所说的那样使用Android的设计原则并在onPostExecute()中处理这一点可能会更好。只需缓存文件,然后将其实际写入onPostExecute()。不应在ui线程上访问文件。setAdapter(arrayAdapter)必须在ui线程上完成。但使用AsyncTask,您可以在ui线程上执行的onPostExecute()中执行此操作。这修复了我遇到的问题,但我仍然不明白原因。我在onProgressUpdate(在UI线程上运行)中将元素添加到我的列表中,遇到了这个异常,当我添加这个异常时,它停止了。请注意:按照其他人所说的那样使用Android的设计原则,并在onPostExecute()中处理这个异常可能会更好。只需缓存文件,然后将其实际写入onPostExecute()。不应在ui线程上访问文件。setAdapter(arrayAdapter)必须在ui线程上完成。但使用AsyncTask,您可以在ui线程上执行的onPostExecute()中执行此操作。这修复了我遇到的问题,但我仍然不明白原因。我在onProgressUpdate(在UI线程上运行)中将元素添加到我的列表中,得到了此异常,当我添加此异常时,它停止了。我在上面的解决方案中添加了一条注释,建议这是更好的方法。我在上面的解决方案中添加了一条注释,建议这是更好的方法。
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