-1

I'm trying to build an app that constantly reads SBS-1 data from a server running dump1090. I thought I'd be better off using a Service rather than an AsyncTask to do so, as at least its lifecycle would be independent of UI components, plus AFAIK AsyncTasks should be used for short operations.

Here's my code:

@Override
public void onCreate() {
    super.onCreate();
    try {
        //TODO: NetworkOnMainThread error
        socket = new Socket(SERVER_URL, SERVER_PORT);
        socketConnected = true;
        inputStream = socket.getInputStream();
        diStream = new DataInputStream(inputStream);
        readerOpen = true;
        ConnectSocket connectSocket = new ConnectSocket();
        Log.d(getClass().toString(), "Socket created!");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

However, as soon as I start up the app, this happens:

FATAL EXCEPTION: main
Process: com.example.[APP_NAME], PID: 2317
java.lang.RuntimeException: Unable to create service com.example.[APP_NAME].services.SocketService: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2887)
at android.app.ActivityThread.-wrap4(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at java.net.Socket.tryAllAddresses(Socket.java:109)
at java.net.Socket.<init>(Socket.java:178)
at java.net.Socket.<init>(Socket.java:150)
at com.example.[APP_NAME].services.SocketService.onCreate(SocketService.java:50)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2877)
at android.app.ActivityThread.-wrap4(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

What am I doing wrong? Do I need to add a new thread to run my service?

CiaranC94
  • 176
  • 4
  • 20
  • 2
    Service is still using main thread ... read about IntentService ... but if you take in account that *app constantly reads* then IntentService is a bad choice ... use Service with new thread ... – Selvin Dec 02 '15 at 11:15
  • use asynctask for network – raj Dec 02 '15 at 11:20
  • Selvin is right, use Intent Service, Service as such runs on the UI thread. Also make sure you have a WakeLock or a WakefulIntentService. – Skynet Dec 02 '15 at 11:34

3 Answers3

3

Android do not allow networking calls on main thread, as it will result into unwanted delays on main thread, so by default it will throw an error.

To do network calls you can use Threads and AsyncTask to make background Network Call.

The easiest way to do networks calls is to use AsysncTask which is basically use for "LowData network calls"

 private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {

            // params comes from the execute() call: params[0] is the url.
            try {
                return downloadUrl(urls[0]);
            } catch (IOException e) {
                return "Unable to retrieve web page. URL may be invalid.";
            }
        }
        // onPostExecute displays the results of the AsyncTask.
        @Override
        protected void onPostExecute(String result) {
            textView.setText(result);
       }
    }

and for background network calls you can use Libraries also like "VOLLEY".

androgo
  • 564
  • 2
  • 8
  • I need to be able to close the socket at some point, once I tried accessing the server in my web browser and the server needed to be reset afterwards as the socket wasn't shut. – CiaranC94 Dec 02 '15 at 16:10
0

Try to use your Socket in background process. Use AsyncTask for that. I had the same issue it got solved. And make sure you have granted permissions in Manifest of INTERNET, ACCESS_NETWORK_STATE.

Tanveer Bulsari
  • 213
  • 1
  • 10
0

Caused by: android.os.NetworkOnMainThreadException It means you should start your service on different thread than Main/UI Thread. When you try to access network resources from Main thread you always will see this exception. More information: How to fix android.os.NetworkOnMainThreadException?

Community
  • 1
  • 1
Unii
  • 1,587
  • 15
  • 33