I use AsyncTask in my Android app to fetch some data from a server. To make the connection, I use the HttpURLConnection class with a timeout of 10 seconds. Now, I would like to show a simple AlertDialog when (if) that time expires, with an OK button that takes the user back to Main Activity. Right now, this is what the relevant part of my app (DoorActivity) looks like:
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(10000);
urlConnection.setRequestMethod("GET");
if (urlConnection.getResponseCode() != 200) {
throw new IOException(urlConnection.getResponseMessage());
}
BufferedReader read = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
jsonString = read.readLine().toString();
} catch (MalformedURLException malformedUrlException) {
System.out.println(malformedUrlException.getMessage());
malformedUrlException.printStackTrace();
} catch (SocketTimeoutException connTimeout) {
showTimeoutAlert();
showTimeoutAlert() method is located in the root class of DoorActivity, and looks like this:
protected void showTimeoutAlert(){
TextView timeoutWarning = new TextView(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog;
timeoutWarning.setText(R.string.conn_timeout_warning);
builder.setView(timeoutWarning);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(DoorActivity.this, MainActivity.class);
startActivity(intent);
}
});
alertDialog = builder.create();
alertDialog.show();
}
Now, when I run this app, with the server deliberately offline, I get the following exception:
java.lang.RuntimeException: An error occured while executing doInBackground()
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
showTimeoutAlert();
should not be called in doInBackground()
. Any code related to UI should go in onPostExecute()
instead.
For example:
private boolean socketTimedOut = false;
@Override
protected String doInBackground(String... params) {
try {
...
} catch (SocketTimeoutException connTimeout) {
this.socketTimedOut = true;
}
}
@Override
protected void onPostExecute(String result) {
if(this.socketTimedOut){
showTimeoutAlert();
}
}
Alternative solution (not recommended):
@Override
protected String doInBackground(String... params) {
try {
...
} catch (SocketTimeoutException connTimeout) {
runOnUiThread(new Runnable() {
public void run() {
showTimeoutAlert();
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With