目录

android.os.NetworkOnMainThreadException

原因

跑老师的代码的时候报这个错,主要内容是编写Android项目时使用OKHttp3网络请求交互,但是老师向我展示了他的代码在他的机器上的正确性。我的就快乐的报错。

分析

后面经过一定的相关知识进行学习发现,虚拟机的版本不同,导致了这个问题。同时在同学的低版本虚拟机上得到了验证。具体的版本规约并未查询到。我方进行试验的是AndroidStudio的虚拟机,Android11的是会报错或请求返回的body无法显示到ui上。Android7以下版本的虚拟机是可以正确将请求结果返回到ui界面上的

解决办法

不操作Android等ui

这是原来的代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                HttpApiClient api = new HttpApiClient();
                String ValidityDate;
                try {
                    ValidityDate = api.validate(mobile);
                    Log.i("id", mobile);
                    Log.i("ValidityDate", ValidityDate);
                    Intent intent = new Intent();
                    intent.putExtra("id", mobile);
                    intent.setClass(IndexActivity.this, LoginActivity.class);
                    IndexActivity.this.startActivity(intent);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    wView.loadUrl("javascript:setMsg('手机号码错误,请重新输入!')");
                }
            });

不使用runOnUiThread,改为一个新线程,并启动他

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                HttpApiClient api = new HttpApiClient();
                String ValidityDate;
                try {
                    ValidityDate = api.validate(mobile);
                    Log.i("id", mobile);
                    Log.i("ValidityDate", ValidityDate);
                    Intent intent = new Intent();
                    intent.putExtra("id", mobile);
                    intent.setClass(IndexActivity.this, LoginActivity.class);
                    IndexActivity.this.startActivity(intent);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    wView.loadUrl("javascript:setMsg('手机号码错误,请重新输入!')");
                }
            }

        }).start();

就完事了。

其他情况

一旦有其他内容需要显示到ui上,需要使用线程之间的通信技术,如Message+Bundle发送,(见我的另一篇博客:点我跳转)Hundle进行接收的办法,或者是同Intent+Bundle进行发送,Hundle进行接收等办法,将数据传输至主线程,主线程将他显示到界面上即可。