Android 网络请求之线程处理

最近在做疫情防控APP开发,其中用到了 OWIN Auth2 远程登录认证
结果在通过HttpURLConnection post 请求的时候发现,在Activity 调用网络请求获取认证状态access_token 的时候发现,报了异常,
android.os.NetworkOnMainThreadException,提示网络请求不能在主线程上运行,查阅资料发现,原来从android 4 开始,不允许进行耗时操作,需要重新开辟子线程。解决方案有两个。

  1. 就是禁用耗时检查和内存泄漏规则,在网络请求前面添加(Activity)。
   if (Build.VERSION.SDK_INT >= 11) {

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads  ().detectDiskWrites().detectNetwork().penaltyLog().build());

StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());

}

这种方法会禁用线程安全和内存泄漏及耗时操作检查,生产模式下慎用。

  1. 下面这种解决方案是官方推荐,符合线程回调和界面流畅度体验。

    网络请求使用开辟主线程上的子线程执行,执行完毕通过主线程处理数据。注意这句话,c++ 处理界面更新要求有回调函数处理,c# 处理界面更新要求使用背景线程或者委托以及线程回调,android 也一样,其实都是一个原理,就是线程内存共享机制,为了保护线程安全

首先定义主线程消息处理函数来更新界面,这里是弹了一个tip.
private Handler mainHandler = new Handler(Looper.getMainLooper())
{
public void handleMessage(android.os.Message msg)
{
TokenInfo tokenInfo = (TokenInfo) msg.obj;
Toast.makeText(LoginActivity.this, tokenInfo.refresh_token, Toast.LENGTH_SHORT).show();
};
};

然后在请求数据的地方,开辟子线程处理网路请求,然后发送消息到主线程处理函数。
new Thread() {
public void run() {
try {
TokenInfo tokenInfo = (TokenInfo) adminService.AdminLogin(adminInfo); //这里是网络请求
Message msg = mainHandler.obtainMessage();
msg.obj = tokenInfo;
mainHandler.sendMessage(msg); //发送主线程处理
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值