ikhwan aja
ikhwan aja

Reputation: 115

service contains HttpURLConnection on android

I make a aplication on android, with contains a service to request server with interval_time. The service run clearly when my app is open. And when I close/stop my app, i got a error in connection.connect(); I want myService can run clearly when my app open or close.

My Code:

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
            }

        });
    }

  }

}

How i run my service:

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

Error:

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)

Upvotes: 0

Views: 1827

Answers (2)

Richard Strand
Richard Strand

Reputation: 743

I believe you have 2 problems here. The network connection is run on the main thread and the timer isn't stopped after app exit.

The Service will be created on the main thread which means the Handler mHandlerConfig is also on the main thread and by extension the post in the Timer which means the network connection is also run on the main thread. If you just move the connection code into the run() method of the Timer the error should go away.

To ensure the timer is stopped after you quit your app you should add code to stop the timer in the onDestroy method of the Service.

Upvotes: 1

Kevin Krumwiede
Kevin Krumwiede

Reputation: 10298

First, you should almost never use a Timer in Android. The trouble you're running into demonstrates why. It forces you to manage threads and thread-safety yourself, when all that is already done for you with AsyncTask. The best way to do things at intervals is usually Handler#postDelayed(...).

Your error is probably a NetworkOnMainThreadException, right? It's crashing because you're calling connect() in the main thread. Once you get past that, you'll probably run into other issues because your TimerTask is trying to run every 10 ms.

Upvotes: 2

Related Questions