如果与AsyncTask一起使用,文本视图上的Settext将崩溃

时间:2015-02-03 03:54:03

标签: android android-asynctask

我正在下载一个大约2 MB的文本文件。当我下载它时,我试图用settext方法向用户显示它。 如果我直接在我的应用程序中应用txt.setText(),应用程序变得如此之慢,所以我在AsyncTask中声明了settext但我的应用程序正在崩溃。我需要快速方法来设置我正在下载的文本。 代码:

private class textviewLoader extends AsyncTask<Void,Void,Void>{
  String msg;
  public textviewLoader(String txtToLoad) {
    msg=txtToLoad;
  }

  @Override
  protected Void doInBackground(Void... params) {
    dataLoaded.setText(msg);
    return null;
  }
}

logcat的:

02-03 09:36:44.930: E/AndroidRuntime(6940): FATAL EXCEPTION: AsyncTask #4
02-03 09:36:44.930: E/AndroidRuntime(6940):                java.lang.RuntimeException: An error occured while executing doInBackground()

02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.lang.Thread.run(Thread.java:856)
02-03 09:36:44.930: E/AndroidRuntime(6940): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5054)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1003)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:4358)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.view.View.invalidate(View.java:10508) 
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.invalidateRegion(TextView.java:4708)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.invalidateCursor(TextView.java:4651)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.spanChange(TextView.java:7649)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:9411)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:688)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.Selection.setSelection(Selection.java:110)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.Selection.setSelection(Selection.java:121)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:302)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.setText(TextView.java:3782)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.setText(TextView.java:3652)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.EditText.setText(EditText.java:100)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.widget.TextView.setText(TextView.java:3627)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at com.dummy.SettingsActivity$textviewLoader.doInBackground(SettingsActivity.java:140)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at com.dummy.SettingsActivity$textviewLoader.doInBackground(SettingsActivity.java:1)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-03 09:36:44.930: E/AndroidRuntime(6940):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-03 09:36:44.930: E/AndroidRuntime(6940):     ... 5 more

4 个答案:

答案 0 :(得分:3)

确保您没有在Async Task的doInBackground中使用setText()方法。 因此你无法在后台线程中进行UI操作。 你应该在onProgressUpdate或onPostExecute

中调用setText()

答案 1 :(得分:1)

正如@Ayaanp所说,你不能在setText()的{​​{1}}中使用“doInBackground方法”。如果您想在Async Task中使用任何UI操作,则应使用doInBackground,例如:

runOnUIThread

你完成了:)现在后台任务将成功执行......

答案 2 :(得分:1)

您无法从主线程以外的任何其他线程更新UI。

@Override
  protected Void doInBackground(Void... params) {
    dataLoaded.setText(msg);
    return null;
  }

setText(msg)正在升级应该仅从主线程运行的UI。 在AsyncTask的onPostExecute()方法中执行此操作。此方法在主线程上运行。 (您不必在postExecute()中调用runOnUIThread())

或者,您可以在doInBackground中调用publishProgress(),该调用调用AsyncTask的onProgressUpdate()方法。您可以使用这些方法进行UI更新。

private class textviewLoader extends AsyncTask<Void, Void, Void> {

    String msg;

    @Override
    protected void onProgressUpdate(Void... values) {

        dataLoaded.setText(msg);// Either update UI here
        super.onProgressUpdate(values);
    }
    public textviewLoader(String txtToLoad) {
        msg = txtToLoad;
    }

    @Override
    protected Void doInBackground(Void... params) {
        publishProgress();//This calls the onProgressUpdate() method
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        dataLoaded.setText(msg);// Either update UI here
    }
}

答案 3 :(得分:0)

希望这可以解决您的问题,每当您想要更新主UI线程时尝试使用runonUIthread

onPostExecute() {
    runOnUiThread(new Runnable() {
                public void run() {
                  txt.setText();  

                }
            });
}`