诗林 发表于 2024-9-14 09:42:06

android.os.NetworkOnMainThreadException

题目

android.os.NetworkOnMainThreadException
详细题目

焦点代码如下:
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

public class HomeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_home);
      try {
            getData();
      } catch (IOException e) {
            e.printStackTrace();
      }
    }


    private List<MyDataType> getData() throws IOException {
      String apiUrl = "http://api-url";

      URL url = new URL(apiUrl);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();

      // 设置请求方法为GET
      connection.setRequestMethod("GET");

      // 获取响应代码
      int responseCode = connection.getResponseCode();

      if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            // 将响应内容转换为Weather对象列表(这里的实现取决于你的服务端返回的数据结构)
            List<MyDataType> dataList = parseResponse(response.toString());

            return dataList;
      } else {
            // 处理错误情况
            System.out.println("HTTP request failed with code: " + responseCode);
            return null;
      }
    }

    // 解析响应内容,将其转换为Weather对象列表
    private static List<MyDataType> parseResponse(String response) {
      // 这里需要根据实际情况解析返回的数据,将其转换为Weather对象列表
      // 请根据你的实际返回数据结构进行实现
      // 示例实现可能需要使用 JSON 解析库(如 Jackson、Gson)来处理 JSON 数据
      return null;
    }
}
控制台报错信息如下:
2024-01-14 11:57:54.617 12108-12108/com.example.assistingagriculture E/AndroidRuntime: FATAL EXCEPTION: main    Process: com.example.assistingagriculture, PID: 12108    android.os.NetworkOnMainThreadException
      at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)      at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116)      at java.net.SocketOutputStream.write(SocketOutputStream.java:161)      at com.android.okhttp.okio.Okio$1.write(Okio.java:78)      at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:157)      at com.android.okhttp.okio.RealBufferedSink.flush(RealBufferedSink.java:222)      at com.android.okhttp.internal.http.Http1xStream.finishRequest(Http1xStream.java:163)      at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:748)      at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)      at com.example.assistingagriculture.HomeActivity.getNearestLongitudeAndLatitude(HomeActivity.java:117)      at com.example.assistingagriculture.HomeActivity.lambda$requestLocation$0$com-example-assistingagriculture-HomeActivity(HomeActivity.java:79)      at com.example.assistingagriculture.HomeActivity$$ExternalSyntheticLambda1.onSuccess(Unknown Source:4)      at com.google.android.gms.tasks.zzn.run(com.google.android.gms:play-services-tasks@@17.2.0:4)      at android.os.Handler.handleCallback(Handler.java:938)      at android.os.Handler.dispatchMessage(Handler.java:99)      at android.os.Looper.loop(Looper.java:223)      at android.app.ActivityThread.main(ActivityThread.java:7656)      at java.lang.reflect.Method.invoke(Native Method)      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)2024-01-14 11:57:54.627 12108-12108/? I/Process: Sending signal. PID: 12108 SIG: 9 解决方案

步骤1、在项目目次\app\src\main\AndroidManifest.xml中添加
<uses-permission android:name="android.permission.INTERNET"/>
具体操作如下图所示:
https://i-blog.csdnimg.cn/blog_migrate/1eb002571b3158d7e9209f9b3658768b.png
表明:数据请求设计网络访问,需要为项目配置网络权限
步骤2、对于上述代码修改,具体修改如下:
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

public class HomeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_home);
      // 此处需修改,添加如下行代码 作用:启动异步任务
      new GetDataAsyncTask().execute();
    }
        // 此处需修改,添加如下类代码 作用:构造异步任务类
    private class GetDataAsyncTask extends AsyncTask<Void, Void, List<MyDataType>> {
      @Override
      protected List<MyDataType> doInBackground(Void... voids) {
            try {
                return getData();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
      }

      @Override
      protected void onPostExecute(List<MyDataType> result) {
            // 在UI线程中处理获取到的数据
            if (result != null) {
                // 处理数据
            } else {
                // 处理错误情况
            }
      }
    }

    private List<MyDataType> getData() throws IOException {
      String apiUrl = "http://api-url";
      URL url = new URL(apiUrl);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();

      // 设置请求方法为GET
      connection.setRequestMethod("GET");

      // 获取响应代码
      int responseCode = connection.getResponseCode();

      if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            // 将响应内容转换为Weather对象列表
            return parseResponse(response.toString());
      } else {
            // 处理错误情况
            System.out.println("HTTP request failed with code: " + responseCode);
            return null;
      }
    }

    // 解析响应内容,将其转换为Weather对象列表
    private static List<MyDataType> parseResponse(String response) {
      // 实现解析逻辑
      return null;
    }
}
题目原因

这个错误是由于笔者在主线程(UI线程)上举行了网络操作,而Android不允许在主线程上执行耗时的网络操作,由于这大概会导致应用界面的卡顿。
解决方案

将网络操作移到后台线程上执行即可。使用异步任务 (AsyncTask) 或者 Thread 来执行网络请求,将网络请求放在 doInBackground 方法中。
参考文献

How can I fix ‘android.os.NetworkOnMainThreadException
’?

部分内容参考chatgpt
原创不易
转载请标明出处
假如对你有所帮助 别忘啦点赞支持哈
https://i-blog.csdnimg.cn/blog_migrate/7b453558c142bce6df770f50778ff3af.jpeg

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: android.os.NetworkOnMainThreadException