4

我正在开发一个 android 应用程序,在每个活动中,我需要将一些数据传递到服务器并在进行下一个活动之前取回响应。如果互联网足够快,该应用程序可以正常工作。但随着速度下降,应用力关闭。如何处理缓慢的互联网连接,以免导致应用程序强制关闭??????

这是代码的一部分

public void onClick(View v) {
    // TODO Auto-generated method stub
    UserFunctions userFunction = new UserFunctions();
    if(userFunction.isNetworkAvailable(getApplicationContext()))
    {
        answer="";
        for(int check1=0;check1<counter2;check1++){
            int check2=0;
            answer=answer+option4[check1]+"|";
            while(check2<counter1){
                if(edTxt[check1][check2].getText().toString().equals("")){
                    answer="";
                    break;
                }
                else{
                    answer=answer+edTxt[check1][check2].getText().toString()+"|";
                }
                check2++;       
            }   
            if(answer.equals("")){
                break;
            }
            else{
                answer=answer+"||";
            }
        }
        if(answer.equals("")){
            Toast.makeText(this, "Please fill all fields", 600).show();
        }
        else{
        userFunction.form1(surveyId,userId , quesNo, answer);
        if(total>0){
            draw(temp); 
        }
        else{
            ques_no++;
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();  
            params.add(new BasicNameValuePair("quesNo", Integer.toString(ques_no)));
            params.add(new BasicNameValuePair("surveyId", surveyId));
            count = getJsonFromURL22(surveyCond, params);           
            j=Integer.parseInt(result);
            if(j==22)
            {
                Toast.makeText(this, "Survey Completed", 600).show();
                Intent home=new Intent(Format16.this, SurveyCompleted.class);
                UserFunctions userFunctions = new UserFunctions();
                userFunctions.full(surveyId);
                Bundle d=new Bundle();
                d.putString("userId", userId);
                home.putExtras(d);
                startActivity(home);
            }
     public String getJsonFromURL22(String url, List<NameValuePair> params){
try{
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);
    httppost.setEntity(new UrlEncodedFormEntity(params));
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    is = entity.getContent();
}catch(Exception e){
    Log.e("log_tag", "Error in http connection"+e.toString());
}
//convert response to string
try{
    BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
    sb = new StringBuilder();
    sb.append(reader.readLine());

    String line="0";
    while ((line = reader.readLine()) != null) {
        sb.append(line);
    }
    is.close();
    result=sb.toString();
}catch(Exception e){
    Log.e("log_tag", "Error converting result "+e.toString());
}
return result;
}
4

5 回答 5

3

由于您没有显示任何代码,我猜您的目标是 Android API 级别 10 或更低,并且您正在 UI 线程中执行所有网络,导致可怕的 App Not Responding(ANR) 错误。解决此问题的一种方法是使用AsyncTask并将所有网络代码移到那里。如果操作正确,AsyncTask'sdoInBackground()将在一个单独的线程中处理您的所有网络,从而允许 UI 保持响应。

它通常是这样工作的:

private class NetworkTask extends AsyncTask<String, Void, String> {

      @Override
      protected String doInBackground(String... params) {
           // Do all networking here, this will work away in a background thread.
           // In your case:
           // HttpResponse response = httpclient.execute(httppost);
           // Must happen here
      }      

      @Override
      protected void onPostExecute(String result) { 
         // dismiss progress dialog if any (not required, runs in UI thread)
      }

      @Override
      protected void onPreExecute() {
         // show progress dialog if any, and other initialization (not required, runs in UI thread)
      }

      @Override
      protected void onProgressUpdate(Void... values) {
// update progress, and other initialization (not required, runs in UI thread)
      }
}

如果您启用StrictMode,或针对 api 版本 11 及更高版本,Android 将NetworkOnMainThreadException在您尝试执行此操作时抛出一个。

于 2012-06-25T06:27:16.710 回答
1

如果互联网足够快,该应用程序可以正常工作。但随着速度下降,应用力关闭。

它清楚地表明您正在 UI 线程上进行网络操作。根据 Google Docs,如果异步操作是在主线程上执行的并且如果花费超过 5 秒,那么您的应用程序将显示强制关闭对话框,这对最终用户来说非常不愉快.

事实上,如果您尝试在最新的 android 版本(即 4.0 或更高版本)上运行此类应用程序,它将不允许您运行应用程序,一旦检测到在主线程上执行异步操作,它将在启动时崩溃。

您必须使用AsyncTaskHandlers执行长时间运行的应用程序。

通过以下博客了解更多信息。

http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html

于 2012-06-25T06:30:43.477 回答
0

使用setConnectionTimeoutsetSoTimeout处理连接超时。

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

并使用AsyncTaskHandlerHandlerThreadrunOnUiThread任何人从服务器获取数据(在后台执行长时间运行的任务)。

于 2012-06-25T06:27:03.793 回答
0

那一定是 ANR 问题而不是 Force Close 问题。

您可以使用 StrictMode 来帮助查找可能长时间运行的操作,例如您可能不小心执行主线程的网络。

或者尝试放置进度条。

于 2012-06-25T06:29:37.240 回答
0

您应该看看这个工具,它可以让您了解导致应用程序速度变慢的原因。ARO 工具旨在诊断这类网络问题http://developer.att.com/developer/forward.jsp?passedItemId=9700312

于 2012-06-25T10:20:45.120 回答