Q:

My app crashes with AsyncTask

I'm new to android and have a problem with my simple application.
I using a very simple counter using AsyncTask.
When I run the app and start the counter, it counts to 10, and then instead of printing "DONE!" the app just crushes, I have no idea why. Here's my code.
(The activity has 3 buttons to create, start and cancel the task).
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;
        }
    }

A:

You cannot update UI from background thread mean the code inside doInBackGround runs on background thread 
 @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;
    }

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

Note:  if you cancel the task then you will find the same crash with textView.setText(String.valueOf(counter));.

Always use generic types and pass the resultant counter value and update UI accordingly.
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
     }
 }

A:

You can't edit View from AsyncTask doInBackground (only main thread). So move setText to onPostExecute
@Override
protected void onPostExecute(Void result)

    textView.setText("DONE!");

}

