我的应用程序崩溃了AsyncTask

问题描述 投票:3回答:2

我是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;
        }
    }
android android-asynctask
2个回答
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
     }
 }

3
投票

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

@Override
protected void onPostExecute(Void result)

    textView.setText("DONE!");

}
© www.soinside.com 2019 - 2024. All rights reserved.