找回密码
 立即注册

Android 网络请求之线程处理

2024-11-26 17:25| 发布者: admin| 查看: 340| 评论: 0

摘要: 最近在做疫情防控APP开发,其中用到了 OWIN Auth2 远程登录认证结果在通过HttpURLConnection post 请求的时候发现,在Activity 调用网络请求获取认证状态access_token 的时候发现,报了异常,android.os.NetworkOnMa ...
 最近在做疫情防控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());

}

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

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

网络请求使用开辟主线程上的子线程执行,执行完毕通过主线程处理数据。注意这句话,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();

路过

雷人

握手

鲜花

鸡蛋

QQ|Archiver|手机版|小黑屋|软件开发编程门户 ( 陇ICP备2024013992号-1|甘公网安备62090002000130号 )

GMT+8, 2025-3-15 01:33 , Processed in 0.039592 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

返回顶部