2012-11-11 20 views
0

我的Android應用程序有一個BroadcastReceiver。開始時,我開始一個Service,它有一個AlarmManager用於每隔10分鐘週期地呼叫我的接收器,並且接收器試圖建立一個http連接。當接收者試圖建立一個httpConnection時,有時需要花費時間在httpConnection.getResponseCode();androidHttpTransport.call(soapAction, envelope);行,並且在這些情況下,android UI(活動)掛起並等待,直到接收者的操作完成。但我認爲BroadcastReceiver的操作是在一個單獨的線程中,它不應該暫停UI線程。Android UI(活動)掛起而BroadcastReceiver試圖使httpConnection

爲什麼會發生這種情況,我該如何糾正它?

我在接收器的HttpConnection:

private Object callWebServiceMethodPublic(String url, 
      String namespace, String methodName, 
      HashMap<String, Object> parameters, String soapAction) 
      throws Exception { 

     //System.setProperty("http.keepAlive", "false"); 

     Log.i("WebService", "URL: " + url); 
     Log.i("WebService", "MethodName: " + methodName); 

     Log.i("SendMapMovements", "1.2.3.1"); 

     URL myurl = new URL(url); 
     URLConnection connection = myurl.openConnection(); 
     connection.setConnectTimeout(20 * 1000); 
     //connection.setRequestProperty("Connection", "close"); 

     HttpURLConnection httpConnection = (HttpURLConnection) connection; 

     Log.i("SendMapMovements", "1.2.3.2"); 

     int responseCode = -1; 
     try { 
      responseCode = httpConnection.getResponseCode(); 

      Log.i("SendMapMovements", "1.2.3.3"); 

     } catch (Exception e1) { 
      if (e1.toString().contains("Network is unreachable")) { 

      } else if (e1.toString().contains("SocketTimeoutException")) { 

      } else { 
       throw e1; 
      } 
     } 
     if (responseCode == HttpURLConnection.HTTP_OK) { 
      httpConnection.disconnect(); 

      Log.i("SendMapMovements", "1.2.3.4"); 

      SoapObject request = new SoapObject(namespace, methodName); 

      if (parameters != null) { 
       String[] keys = new String[0]; 
       keys = (String[]) parameters.keySet().toArray(keys); 
       Object[] vals = (Object[]) parameters.values().toArray(); 

       for (int i = 0; i < parameters.size(); i++) { 
        request.addProperty(keys[i], vals[i]); 
        Log.i("WebService", keys[i] + ": " + vals[i]); 
       } 
      } 

      Log.i("SendMapMovements", "1.2.3.5"); 

      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
        SoapEnvelope.VER11); 
      envelope.dotNet = true; 

      envelope.setOutputSoapObject(request); 
      HttpTransportSE androidHttpTransport = new HttpTransportSE(url, 
        TimeOutInSeconds * 1000); 

      Log.i("SendMapMovements", "1.2.3.6"); 

      try { 
       androidHttpTransport.call(soapAction, envelope); 

       Log.i("SendMapMovements", "1.2.3.7"); 

      } catch (Exception e) { 
       if (e.toString().contains("XmlPullParserException")) { 
        throw new Exception(...); 
       } 
      } 

      Object so = envelope.getResponse(); 
      System.gc(); 

      return so; 

     } else { 
      httpConnection.disconnect(); 
      Log.i("SendMapMovements", "1.2.3.8"); 
      String strErrorDescription = getHttpErrorDescription(responseCode); 
      throw new Exception(strErrorDescription); 
     } 
    } 
+0

*但我認爲BroadcastReceiver的操作是在一個單獨的線程中,它不應該暫停UI線程。* - 你的假設是不正確的。 – Luksprog

+0

@Luksprog我應該在接收器中定義一個AsyncTask嗎? – breceivemail

+0

如果接收器設置在清單中,那麼您不應該啓動一個新線程或'AsyncTask',因爲Android可能會在'onReceive'完成後終止進程。在這種情況下,你應該使用'Service'(或者更好的'IntentService')。 – Luksprog

回答

1

你必須運行你的連接代碼whithin新Thread,而不是UI Thread (Main Thread),因爲BroadcastReceiver和你Activity在同一線程上運行。

+0

我應該在接收器中定義一個AsyncTask嗎? – breceivemail

+0

正如我看到你的代碼,沒有必要在AsyncTask中完成,只需在新線程中完成。 –