0

The application I'm building right now has problems when using HTTP post. When timeout occures, the application crashes with the following error:

06-20 19:01:35.715: E/Timeout Exception:(3802): java.net.SocketTimeoutException
06-20 19:01:35.720: W/dalvikvm(3802): threadid=15: thread exiting with uncaught exception (group=0x40c4d1f8)
06-20 19:01:35.865: D/dalvikvm(3802): GC_CONCURRENT freed 67K, 18% free 13640K/16519K, paused 7ms+3ms
06-20 19:01:35.870: E/AndroidRuntime(3802): FATAL EXCEPTION: AsyncTask #4
06-20 19:01:35.870: E/AndroidRuntime(3802): java.lang.RuntimeException: An error occured while executing doInBackground()
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.lang.Thread.run(Thread.java:856)
06-20 19:01:35.870: E/AndroidRuntime(3802): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.os.Handler.<init>(Handler.java:121)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.app.Dialog.<init>(Dialog.java:107)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.app.AlertDialog.<init>(AlertDialog.java:114)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.app.AlertDialog$Builder.create(AlertDialog.java:913)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.app.AlertDialog$Builder.show(AlertDialog.java:931)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at com.on_d_mand.live_evenementen.Helper.showAlert(Helper.java:357)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at com.on_d_mand.live_evenementen.SyncData.doInBackground(SyncData.java:99)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at com.on_d_mand.live_evenementen.SyncData.doInBackground(SyncData.java:1)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
06-20 19:01:35.870: E/AndroidRuntime(3802):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-20 19:01:35.870: E/AndroidRuntime(3802):     ... 5 more

This is how the source looks like:

//ON PRE EXECUTE
protected void onPreExecute(){

    if(MESSAGE != null){
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage(MESSAGE);
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }
}

//DO IN BACKGROUND
@Override
protected String doInBackground(String... urls) {
    //SYNC DATA WITH THE SERVER
    try{

        HttpParams httpParameters = new BasicHttpParams();
        // Set the timeout in milliseconds (30 seconds) until a connection is established.
        // The default value is zero, that means the timeout is not used. 
        int timeoutConnection = 30 * 1000;
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        // Set the default socket timeout (SO_TIMEOUT) 
        // in milliseconds (30 seconds) which is the timeout for waiting for data.
        int timeoutSocket = 30 * 1000;
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

        HttpClient httpclient = new DefaultHttpClient(httpParameters);
        HttpPost httppost = new HttpPost(urls[0]);
        httppost.setEntity(new UrlEncodedFormEntity(preparedInformation));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        IS = entity.getContent();

    }catch (SocketTimeoutException ste){
        Log.e("Timeout Exception: ", ste.toString());
    }
    catch(Exception e){
        Log.e("log_tag", "Error in http connection"+e.toString());
    }

    //CONVERT DATA INTO STRING
    try{
        BufferedReader reader = new BufferedReader(new InputStreamReader(IS,"iso-8859-1"),8);
            SB = new StringBuilder();
            SB.append(reader.readLine() + "\n");
            String line="0";

            while ((line = reader.readLine()) != null) {
                SB.append(line + "\n\n");
            }

            IS.close();
            this.result = SB.toString();
    }
    catch(Exception e){
        Log.e("log_tag", "Error converting result "+e.toString());
    }

    return this.result;
}

Caused by Java RuntimeException... Ok, so what? This problem needs to be avoided because it's the very last bug in the application I have right now. Any help is MUCH appreciated.

Aerial
  • 1,185
  • 4
  • 20
  • 42

2 Answers2

1

You problem is show() method.

The method show() must be called from UI thread.

You are able to call this method only in onPogressUpdate() or onPostExecute() or call show() before you execute task. Also showAlert() you can't call in doInBackground().

You must know that you can call nothing which update UI in background thread. So for update your UI use only onProgressUpdate() method or like i meant onPostExecute().

EDIT:

catch(Exception ex){
   Log.e("log_tag", "Error in http connection"+e.toString());
   return ex.toString();
}
Simon Dorociak
  • 33,374
  • 10
  • 68
  • 106
  • Yeah, thanks for the information. I did remove the methods, but the problem still occures... – Aerial Jun 20 '12 at 17:20
  • which type of problems? tell me something. – Simon Dorociak Jun 20 '12 at 17:21
  • so if you removed any code that update UI from your worker thread and it doesnt work, problem is elsewhere. i wrote remove your show() method from onPreExecute, you should init your progressDialog before execute task. – Simon Dorociak Jun 20 '12 at 17:29
  • Thanks! it stopped crashing! How can I still show a Toast or an AlertDialog when timeout occures? I used the onProgressUpdate() method and nothing occures... – Aerial Jun 20 '12 at 17:33
  • ah ok you dont want to change generic so just return in your catch string and then in your onPostExecute call Toast or AlertDialog. – Simon Dorociak Jun 20 '12 at 17:53
1

Remove helper.showAlert() method from the doInBackGround() method, You can't run on Main thread from worker thread (can not update MainUI Thread).

Instead of it, use onProgressUpdate() and use helper.showAlert() from that.

UPDATE:

catch (SocketTimeoutException ste){
        Log.e("Timeout Exception: ", ste.toString());
        return ste.toString();
    }
    catch(Exception e){
        Log.e("log_tag", "Error in http connection"+e.toString());
        return e.toString();
    }


protected void onPostExecute(String result) {
    Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
 }
user370305
  • 108,599
  • 23
  • 164
  • 151
  • I removed the helper.showAlert() and the other dialog.show() method to be sure if it works, but the problem still occures. – Aerial Jun 20 '12 at 17:21
  • helper.showAlert() does not show in the onProgressUpdate() method. What can I do to show an AlertDialog? – Aerial Jun 20 '12 at 17:38