我的应用程序崩溃了AsyncTask

时间:2017-12-21 14:40:51

标签: android android-asynctask

我是Android的新手,我的简单应用程序出了问题。 我使用非常简单的计数器使用AsyncTask。

当我运行应用程序并启动计数器时,它计数到10,然后不是打印“完成!”应用程序只是粉碎,我不知道为什么。这是我的代码。 (该活动有3个按钮来创建,启动和取消任务)。

public class AsyncTaskActivity extends AppCompatActivity {

    AsyncTask myAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
    }

    public static void startActivity(Context context){

        Intent intent = new Intent(context, AsyncTaskActivity.class);
        context.startActivity(intent);

    }

    public void createNewTask(View view) {

        TextView textView = findViewById(R.id.text_view_id);
        myAsyncTask = new MyAsyncTask(textView);
    }

    public void startTask(View view) {

        myAsyncTask.execute();
    }

    public void cancelTask(View view) {

        myAsyncTask.cancel(true);
    }

    private static class MyAsyncTask extends AsyncTask{

        private TextView textView;

        public MyAsyncTask(TextView textView){

            this.textView = textView;
        }

        @Override
        protected Object doInBackground(Object[] objects) {


            for(int counter = 0; counter <= 10; counter ++){

                if(!isCancelled()) {
                    textView.setText(String.valueOf(counter));
                    SystemClock.sleep(500);
                }
                else
                    break;
            }

            textView.setText("DONE!");
            return null;
        }
    }

2 个答案:

答案 0 :(得分:4)

您无法从后台线程更新UI意味着doInBackGround内的代码在后台线程上运行

 @Override
 protected Object doInBackground(Object[] objects) {
     for(int counter = 0; counter <= 10; counter ++){

         if(!isCancelled()) {
             textView.setText(String.valueOf(counter));
             SystemClock.sleep(500);
         }
         else
             break;
        }

        textView.setText("DONE!");
        // ^^^^^ crash , cannot update UI from background thread
        return null;
    }

所以改为使用onPostExecuted

 protected void onPostExecute(Long result) {
        textView.setText("DONE!");
 }

注意:如果您取消任务,那么您将发现与textView.setText(String.valueOf(counter));相同的崩溃。

始终使用generic类型并传递结果计数器值并相应地更新UI。

private static class MyAsyncTask extends AsyncTask<Void,Void,Integer>{

    private TextView textView;

    public MyAsyncTask(TextView textView){

        this.textView = textView;
    }


     protected Long doInBackground(Void... obj) {
        for(int counter = 0; counter <= 10; counter ++){

            if(!isCancelled()) {
                SystemClock.sleep(500);
                return counter;
            }
            else
                break;
        }
         return null;
     }


     protected void onPostExecute(Integer result) {
        if(result != null)
            textView.setText(String.valueOf(result));
        else
            textView.setText(String.valueOf("Done"));
            // your current code will set done no matter the task is cancelled or not
     }
 }

答案 1 :(得分:3)

您无法编辑AsyncTask doInBackground中的View(仅限主线程)。所以将setText移动到onPostExecute

@Override
protected void onPostExecute(Void result)

    textView.setText("DONE!");

}