Reputation: 859
I have the class above in my activity and run it from a activitie's OnCreate method.
class UpdateTask extends AsyncTask<String, Void, Void>{
@Override
protected Void doInBackground(String... params) {
Log.d(this.toString(), "-> doInBackground");
HttpResponse response;
try {
HttpParams params1 = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params1, 3000);
HttpConnectionParams.setSoTimeout(params1, 5000);
HttpClient httpclient = new DefaultHttpClient(params1);
Log.d(this.toString(), "HTTP GET to " + "http://www.google.com");
response = httpclient.execute(new HttpGet("http://www.google.com"));
//RequestTask t = new RequestTask();
//response = t.doIt("http://www.google.com");
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String responseString = out.toString();
EventItem ei = new EventItem(responseString, responseString, null);
addEventItemToContent(ei, ContentStatus.ACTIVE);
Log.d(this.toString(), "doInBackground -success->");
} else {
Log.d(this.toString(), "doInBackground -something wrong->");
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Интернет недоступен", Toast.LENGTH_LONG).show();
}
LogCat says:
11-11 01:31:19.100: D/com.rkovalev.first.app.MainActivity$UpdateTask@4138ae20(9956): -> doInBackground
11-11 01:31:19.100: D/com.rkovalev.first.app.MainActivity$UpdateTask@4138ae20(9956): HTTP GET to http://www.google.com
11-11 01:31:59.560: W/dalvikvm(9956): threadid=11: thread exiting with uncaught exception (group=0x409961f8)
11-11 01:31:59.580: E/AndroidRuntime(9956): FATAL EXCEPTION: AsyncTask #1
11-11 01:31:59.580: E/AndroidRuntime(9956): java.lang.RuntimeException: An error occured while executing doInBackground()
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.os.AsyncTask$3.done(AsyncTask.java:278)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.lang.Thread.run(Thread.java:856)
11-11 01:31:59.580: E/AndroidRuntime(9956): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.os.Handler.<init>(Handler.java:121)
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.widget.Toast$TN.<init>(Toast.java:317)
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.widget.Toast.<init>(Toast.java:91)
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.widget.Toast.makeText(Toast.java:233)
11-11 01:31:59.580: E/AndroidRuntime(9956): at com.rkovalev.first.app.MainActivity$UpdateTask.doInBackground(MainActivity.java:207)
11-11 01:31:59.580: E/AndroidRuntime(9956): at com.rkovalev.first.app.MainActivity$UpdateTask.doInBackground(MainActivity.java:1)
11-11 01:31:59.580: E/AndroidRuntime(9956): at android.os.AsyncTask$2.call(AsyncTask.java:264)
11-11 01:31:59.580: E/AndroidRuntime(9956): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-11 01:31:59.580: E/AndroidRuntime(9956): ... 5 more
There is an error in my code or I should handle exceptions from an another place?
UPD: Question in the code above:
class UpdateTask extends AsyncTask<String, Integer, Void>{
@Override
protected Void doInBackground(String... params) {
this.onProgressUpdate(0);
return null;
}
@Override
protected void onProgressUpdate(Integer... codes) {
Toast.makeText(getApplicationContext(),
"onPr.Upd.: why I haven't access to main ui thread???", Toast.LENGTH_LONG).show();
}
@Override
protected void onPostExecute(Void res) {
Toast.makeText(getApplicationContext(),
"onPost.Ex.: I have access to main thread!", Toast.LENGTH_LONG).show();
}
}
Upvotes: 0
Views: 98
Reputation: 86948
The root problem is that you are trying to display a Toast from outside the UI thread, here:
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Интернет недоступен", Toast.LENGTH_LONG).show();
}
You cannot interact with UI elements from a different thread.
You should catch the exception (handle it gracefully), then call onPostExecute()
to inform the Activity there is an error so that the Activity can display this Toast.
Upvotes: 2
Reputation: 5157
Instead of directly trying to do all the UI notification stuff in your doInBackground which is itself not a UI thread.
You should use the methods that have access to the UI thread e.g onProgressUpdate,onPostExecute. Something like this in your case.
catch (Exception e) {
publishProgress(error_code); // The error code for identifying
}
And in your onProgressUpdate method
@Override
protected void onProgressUpdate(Integer... error_codes) {
if(error_codes[0] == my_desired_error_code){
Toast.makeText(getApplicationContext(), "Интернет недоступен", Toast.LENGTH_LONG).show();
}
}
Basically your flow should be like this for notifying on the UI .
Upvotes: 0