ductran
ductran

Reputation: 10203

AsyncTask cannot work in thread android

I use AsyncTask to change text of TextView like this:

    private class LongOperation extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        for (String url : urls) {
            response += url;
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        textView.setText(result);
    }
}

Everything will fine if I call it in OnClick event:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    textView = (TextView) findViewById(R.id.txt);
    Button button = (Button)this.findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
          new LongOperation().execute(new String[]{"Hello"});
        }
      });
   }

But the problem when I called it in my thread, the program forced close

this.closeButton.setOnClickListener(new OnClickListener() {
         @Override
        public void onClick(View v) {
          Thread t= new Thread(){               
           @Override
             public void run(){                                     
              try{
                    //Do something
                    //Then call AsyncTask
                new LongOperation().execute(new String[]{"Hello"});

               }catch(Exception e){}
         }
        };      
         t.start();
        }
      });

Where am I wrong? I dont' understand how difference call AsyncTask in thread or not.

Upvotes: 1

Views: 5014

Answers (3)

Zsombor Erdődy-Nagy
Zsombor Erdődy-Nagy

Reputation: 16914

Adding to what the others have said: I think you can use AsyncTask to launch off a task in another thread, even if you start the AsyncTask from a different thread than the UI already.

But in that case, the only way you'll only be able to modify the UI indirectly, for example: pass the handler of the current Activity somehow to this AsyncTask instance, and send messages to it (handler messages get processed on the UI thread). Or use broadcast intents that the Activity catches and updates the UI accordingly, etc. These solutions seem to be overkills though.

Upvotes: 1

Phil Lello
Phil Lello

Reputation: 8639

I recommend you consult the AsyncTask documentation and Processes and Threads for a better understanding of how it works. Essentially, you should create your AsyncTask subclass on the main thread.

When you call AsyncTask.execute(), your provided, AsyncTask.onPreExecute is called on the main thread, so you can do UI setup.

Next AsyncTask.doInBackground method is called, and runs in its own thread.

Finally, when your AsyncTask.doInBackground method completes, a call is made to AsyncTask.onPostExecute on the main thread, and you can do any UI cleanup.

If you need to update the UI from within your AsyncTask.doInBackground method, call AsyncTask.publishProgress, which will invoke onProgressUpdate in the main thread.

Upvotes: 8

K-ballo
K-ballo

Reputation: 81349

When you call it from the UI thread, the associated Context is the running Activity. When you call it from a regular thread, there is no valid Context associated with that thread. AsyncTask executes in its own thread, you shouldn't be creating its own thread. If that is actual code, then you have missunderstood the point of AsyncTask. Search for tutorials on how to use it.

Upvotes: 2

Related Questions