android报错android.os.NetworkOnMainThreadException

菜鸟新手写android应用demo,遇到android.os.NetworkOnMainThreadException异常,根据大神的指示,去查了一下官方文档,上面是这样说的:

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

在主线程中试图进行网络操作会抛出此异常。

This is only thrown for applications targeting the Honeycomb SDK or higher.
Applications targeting earlier SDK versions are allowed to do networking on 
their main event loop threads, but it's heavily discouraged.

这个异常只会在使用Honeycomb SDK或更高版本应用上才会抛出(这个版本应该是api level 11 android 3.0),
早于此版本的sdk允许在主线程中进行网络操作,当然,谷歌工程师强烈不建议这么做

英语水平有限,就只能翻译到这种程度了,见谅。

查阅了一下诸位大神的指南,总结以下两种解决方法:

1.简单粗暴型

//修改系统策略,放开所有的权限
//代码添加到onCreate回调方法中即可

if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
    }

ps:这种方式非常不被推荐,这种做法有点矫枉过正,放开所有的限制,看一下源码中的permitAll的方法与解释,如同为了怕麻烦而取消安检一样,危险等级较高,不推荐

/** Disable the detection of everything. */
/*取消所有检测*/
public Builder permitAll() {
      return disable(ALL_THREAD_DETECT_BITS);
}

2.采用独立线程处理网络请求

将网络请求等耗时操作放在独立的线程中,主线程通过handler获取数据。

代码如下

 /**
  * 处理网络请求的线程
  */
private class RequestThread extends Thread {
        @Override
        public void run() {           
            Message msg = new Message();
            Bundle data = new Bundle();
            //耗时操作
            //为节省篇幅,此处省略网络请求和处理数据的代码
            
            data.putString("value", string);
            msg.setData(data);
            msg.what = 1;
            handler.sendMessage(msg);
        }
}

Handler handler = new Handler() {
     @Override
     public void handleMessage(Message msg) {
         super.handleMessage(msg);
         if (msg.what == 1) {
             Bundle data = msg.getData();
             String val = data.getString("value");
             //获取到数据后,进行修改UI等操作
             //请注意,如需要修改主线程的UI,需要再handler中进行,否在会抛出异常。
             tvCode.setText(val);

         }
     }
};

然后可以在按钮点击等其他事件中开启线程,处理网络请求等耗时操作。需要注意的是,修改主UI必须在主线程中,否则会抛出异常。

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值