android.os.NetworkOnMainThreadException при попытке использовать сервис
Я пытаюсь создать приложение, которое постоянно читает данные SBS-1 с сервера, на котором выполняется dump1090. Я подумал, что для этого лучше использовать Service, а не AsyncTask, поскольку, по крайней мере, его жизненный цикл будет независимым от компонентов пользовательского интерфейса, плюс 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 ответа
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".
Вызывается: android.os.NetworkOnMainThreadException Это означает, что вы должны запускать свой сервис в другом потоке, чем в Main/UI Thread. При попытке доступа к сетевым ресурсам из основного потока вы всегда увидите это исключение. Более подробная информация: Как исправить android.os.NetworkOnMainThreadException?
Попробуйте использовать свой сокет в фоновом процессе. Используйте AsyncTask для этого. У меня была та же проблема, которая была решена. И убедитесь, что вы предоставили разрешения в Манифесте ИНТЕРНЕТА, ACCESS_NETWORK_STATE.