【问题标题】:Error when timeout occures发生超时时出错
【发布时间】:2012-06-20 17:08:24
【问题描述】:

我现在正在构建的应用程序在使用 HTTP post 时出现问题。发生超时时,应用程序崩溃并出现以下错误:

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

源代码如下所示:

//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;
}

由 Java RuntimeException 引起...好吧,那又怎样?这个问题需要避免,因为它是我现在拥有的应用程序中的最后一个错误。非常感谢任何帮助。

【问题讨论】:

    标签: android timeout android-asynctask progressdialog runtimeexception


    【解决方案1】:

    你的问题是show() 方法。

    方法 show() 必须从 UI 线程调用。

    您只能在onPogressUpdate()onPostExecute() 中调用此方法或在执行任务之前调用show()。还有showAlert()你不能打电话给doInBackground()

    你必须知道你不能在background thread 中调用更新UI 的任何东西。因此,要更新您的 UI,请仅使用 onProgressUpdate() 方法或我的意思是 onPostExecute()

    编辑:

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

    【讨论】:

    • 是的,感谢您提供的信息。我确实删除了方法,但问题仍然存在......
    • 哪类问题?告诉我一些事情。
    • 因此,如果您从工作线程中删除了任何更新 UI 的代码并且它不起作用,那么问题就出在其他地方。我写了从 onPreExecute 中删除你的 show() 方法,你应该在执行任务之前初始化你的 progressDialog。
    • 谢谢!它停止崩溃了!发生超时时如何仍然显示 Toast 或 AlertDialog?我使用了 onProgressUpdate() 方法,没有任何反应...
    • 啊,好吧,你不想改变泛型,所以只需返回你的 catch 字符串,然后在你的 onPostExecute 调用 Toast 或 AlertDialog 中。
    【解决方案2】:

    doInBackGround() 方法中删除helper.showAlert() 方法,您不能从工作线程在主线程上运行(不能更新MainUI 线程)。

    使用 onProgressUpdate() 并从中使用 helper.showAlert() 来代替它。

    更新:

    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();
     }
    

    【讨论】:

    • 我删除了 helper.showAlert() 和另一个 dialog.show() 方法以确保它是否有效,但问题仍然存在。
    • helper.showAlert() 不会显示在 onProgressUpdate() 方法中。我该怎么做才能显示 AlertDialog?
    猜你喜欢
    • 2011-12-07
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多