2015-09-25 55 views
0

我在android上做了一個應用程序,包含一個服務請求服務器interval_time。該服務在我的應用程序打開時運行得很清楚。當我關閉/停止我的應用程序時,我在connection.connect()中出現錯誤;我希望myService可以在我的應用程序打開或關閉時清晰地運行。服務包含Android上的HttpURLConnection android

我的代碼:

public class RequestService extends Service { 

    String interval_config; 

    private Handler mHandlerConfig = new Handler(); 

    private Timer mTimerConfig = null; 
    public static long CONFIG_INTERVAL=10; 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

@Override 
public void onCreate() { 
     if(mTimerConfig != null){ 
      mTimerConfig.cancel(); 
     } else { 
      mTimerConfig = new Timer(); 
     } 
     mTimerConfig.scheduleAtFixedRate(new ConfigTimerTask(), 0, CONFIG_INTERVAL); 
    } 

class ConfigTimerTask extends TimerTask { 
    @Override 
    public void run() { 
     // run on another thread 
     mHandlerConfig.post(new Runnable() { 

      @Override 
      public void run() { 
       URL url = new URL(/*URL address*/); 
      HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
      connection.setReadTimeout(15000); 
      connection.setConnectTimeout(15000); 
      connection.setRequestMethod("POST"); 
      connection.setDoInput(true); 
      connection.setDoOutput(true); 
      connection.connect(); //error here 
      } 

     }); 
    } 

    } 

} 

我如何運行我的服務:

startService(new Intent(this, RequestService.class)); 

錯誤:

2517-2517/com.sia.siav2 E/AndroidRuntime﹕ FATAL EXCEPTION: main 
android.os.NetworkOnMainThreadException 
     at  android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 
     at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
     at java.net.InetAddress.getAllByName(InetAddress.java:214) 
     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70) 
     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50) 
     at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340) 
     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87) 
     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 
     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316) 
     at libcore.net.http.HttpEngine.connect(HttpEngine.java:311) 
     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) 
     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) 
     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81) 
     at com.sia.siav2.service.RequestService.jsonFunction(RequestService.java:277) 
     at com.sia.siav2.service.RequestService.memintaIntervalNotif(RequestService.java:141) 
     at com.sia.siav2.service.RequestService$ConfigTimerTask$1.run(RequestService.java:106) 
     at android.os.Handler.handleCallback(Handler.java:725) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5041) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
     at dalvik.system.NativeStart.main(Native Method) 
+1

你有什麼錯誤? –

+0

NetworkOnMainThreadException上的錯誤@ Some1pRo –

回答

2

首先,你應該幾乎從來沒有在Android中使用Timer。您遇到的麻煩說明了原因。它會強制你自己管理線程和線程安全,當你用AsyncTask完成所有這些工作時。間隔做事的最好方法通常是Handler#postDelayed(...)

您的錯誤可能是NetworkOnMainThreadException,對吧?它正在崩潰,因爲你在主線程中調用了connect()。一旦你過去了,你可能會遇到其他問題,因爲你的TimerTask試圖每10毫秒運行一次。

+0

那麼我該怎麼做kevin?我希望我的應用程序能夠以間隔時間向服務器請求.. –

+0

@ikhwanaja使用[Handler#postDelayed(...)](http://developer.android.com/reference/android/os/Handler.html#postDelayed% 28java.lang.Runnable,%20long%29),並讓任務在每次運行時重新發布。 –

+0

好的,謝謝你的幫助@kevin –

1

我相信你在這裏有兩個問題。網絡連接在主線程上運行,並且應用程序退出後計時器不會停止。

該服務將在主線程上創建,這意味着處理程序mHandlerConfig也位於主線程中,並且通過擴展名在定時器中表示網絡連接也在主線程上運行。如果您只是將連接代碼移動到Timer的run()方法中,則錯誤應該消失。

要確保計時器在您退出應用程序後停止,您應該添加代碼以停止服務的onDestroy方法中的計時器。