尝试使用服务时android.os.NetworkOnMainThreadException

时间:2015-12-02 11:14:08

标签: android sockets network-programming android-service android-runonuithread

我正在尝试构建一个不断从运行dump1090的服务器读取SBS-1数据的应用程序。我认为使用Service而不是AsyncTask会更好,因为至少它的生命周期将独立于UI组件,而且AFAIK AsyncTasks应该用于简短操作。

这是我的代码:

@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();
    }
}

然而,只要我启动应用程序,就会发生这种情况:

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) 

我做错了什么?我是否需要添加新线程才能运行我的服务?

3 个答案:

答案 0 :(得分:2)

Android不允许在主线程上进行网络调用,因为它会导致主线程上出现意外延迟,因此默认情况下会引发错误。

要进行网络呼叫,您可以使用Threads和AsyncTask进行后台网络呼叫。

进行网络呼叫最简单的方法是使用AsysncTask,它基本上用于“LowData网络呼叫”

 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);
       }
    }

对于后台网络调用,您可以使用像“VOLLEY”这样的库。

答案 1 :(得分:0)

尝试在后台进程中使用Socket。 使用AsyncTask。我遇到了同样的问题。 并确保您已在INTERNET的清单中授予了权限,ACCESS_NETWORK_STATE。

答案 2 :(得分:0)

  

引起:android.os.NetworkOnMainThreadException   这意味着您应该在与Main / UI Thread不同的线程上启动服务。当您尝试从主线程访问网络资源时,您将始终看到此异常。更多信息:How to fix android.os.NetworkOnMainThreadException?