Android:AsyncTask onPreExecute()方法不在UI线程中执行

时间:2013-05-07 10:02:56

标签: android android-asynctask thread-safety

我有从线程执行的AsyncTask 。在onPreExecute()方法中,我想更改一些TextView但我收到以下错误(回顾):

05-07 11:53:02.039: E/AndroidRuntime(7062): FATAL EXCEPTION: processBarcodeThread
05-07 11:53:02.039: E/AndroidRuntime(7062): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
.....
05-07 11:53:02.039: E/AndroidRuntime(7062):     at android.widget.TextView.setText(TextView.java:2573)
05-07 11:53:02.039: E/AndroidRuntime(7062):     at it.mbm.droid.activity.fragment.LabelAnagFragment$ReadFromServerTask.onPreExecute(LabelAnagFragment.java:301)
05-07 11:53:02.039: E/AndroidRuntime(7062):     at android.os.AsyncTask.execute(AsyncTask.java:391)

这意味着onPreExecute()不会在UI线程上执行,但根据Android文档:

  

onPreExecute(),在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

那么,我在哪里做错了?

3 个答案:

答案 0 :(得分:6)

您似乎是从后台线程调用execute()上的AsyncTask。如果您阅读了AsyncTask的文档,您会发现这不受支持:

  

此类必须遵循一些线程规则   正常工作:

     
      
  • 必须在UI线程上加载AsyncTask类。这个完成了   自JELLY_BEAN起。
  •   
  • 必须创建任务实例   UI线程。
  •   必须在UI线程上调用
  • execute(Params ...)。   ...
  •   

因此,请更改您的代码,以便从主应用程序主题中调用execute()上的AsyncTask

答案 1 :(得分:0)

尝试将更改放入onProgressUpdate方法。类似的东西:

private class MyAsyncTask extends AsyncTask<Void, String, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        while (!isCancelled()) {    

                    publishProgress("putThisStringToTextView");
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        updateTextView(values[0]);
    }

    private void updateTextView(String text) {
        final Activity activity = getActivity();

        final TextView myTextView = ((TextView) activity.findViewById(R.id.my_txt_view));
         if (textView == null) {
        return;
     }
         textView.setText(text);
         this.cancel(true);
    }
}

答案 2 :(得分:0)

你可能在这些步骤中失败了:

必须在UI线程上加载AsyncTask类。这是自动完成的 Build.VERSION_CODES.JELLY_BEAN 。 必须在UI线程上创建任务实例。

必须在UI线程上调用

execute(java.lang.Object [])。