【转载】Android 3 开始 Activity MainThread中不能执行http通信了
2013-07-25 09:35
337 查看
Google从3开始,强制默认禁止UI主线程发起通信请求,看来Google越来越重视UI体验了。这是好事情
对应的方法, 有两个:
1. 可以临时性的 在Activity初期化的时候,指定StickMode,可以绕开这个OS check, 不过别把这个当彻底的解决方法
具体说起来, 就是在要通信的画面的Activity的OnCreate方法中如下配置stickMode
2. 永久性的对应, 把通信的代码转移到子线程里去做, 比较靠谱的是new一个AyncTask,在里面做通信
有几个细节性的问题是,
第一, 一般原有通信的代码都是共通的API, 被许多个Activity调用, 一个良好的修改方法是在共通API里面new AyncTask
第二, 通信的API一般来说都是同步的, 你通信,然后画面主线程需要堵塞住,等待API的通信结果,再决定下面的业务逻辑的走向。
所以,这块可以采取 AyncTask.get(), 让主线程堵塞,直到通信结束。 当然,如果你需要将通信异步的话, 可以用Handler机制来解决
第三, 用来通信的AyncTask中不能再请求其他子线程
具体的代码如下
a. 异步的http请求线程
b.调用的代码
对应的方法, 有两个:
1. 可以临时性的 在Activity初期化的时候,指定StickMode,可以绕开这个OS check, 不过别把这个当彻底的解决方法
具体说起来, 就是在要通信的画面的Activity的OnCreate方法中如下配置stickMode
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads() .detectDiskWrites().detectNetwork().penaltyLog().build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects() .detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath().build());
2. 永久性的对应, 把通信的代码转移到子线程里去做, 比较靠谱的是new一个AyncTask,在里面做通信
有几个细节性的问题是,
第一, 一般原有通信的代码都是共通的API, 被许多个Activity调用, 一个良好的修改方法是在共通API里面new AyncTask
第二, 通信的API一般来说都是同步的, 你通信,然后画面主线程需要堵塞住,等待API的通信结果,再决定下面的业务逻辑的走向。
所以,这块可以采取 AyncTask.get(), 让主线程堵塞,直到通信结束。 当然,如果你需要将通信异步的话, 可以用Handler机制来解决
第三, 用来通信的AyncTask中不能再请求其他子线程
具体的代码如下
a. 异步的http请求线程
class HttpReqTask extends AsyncTask<Object, Object, HttpResponse>{ @Override protected HttpResponse doInBackground(Object... params){ String url = (String)params[0]; String session = (String)params[1]; List<NameValuePair> paierList = (ArrayList<NameValuePair>)params[2]; HttpClient httpclient = (HttpClient)params[3]; HttpPost request = new HttpPost(url); HttpResponse response = null; if (session != null && session.length() != 0) { request.addHeader(SM.COOKIE, "sessid" + "=" + session); } try { request.setEntity(new UrlEncodedFormEntity(paierList, HTTP.UTF_8)); response = httpclient.execute(request); } catch (Exception e) { throw new RuntimeException(e); } return response; } }
b.调用的代码
Object []param = new Object[4]; param[0] = url; param[1] = session; param[2] = paierList; param[3] = httpclient; AsyncTask res = new HttpReqTask().execute(param); HttpResponse response = null; try { response = (HttpResponse) res.get(); } catch (Exception e) { Log.e("HttpAPI.callHttpPost()", "Error", e); }
相关文章推荐
- 【Android】init -> Zygote(app_main) -> SystemServer(SystemServer.main)/AppProcess(ActivityThread.main)
- Android 使用URL,URLConnection,HttpConnection 不能通信的问题
- 在Activity中启动一个网络连接遇到android.os.NetworkOnMainThreadException
- 安卓与服务器进行Http通信抛出 NetworkOnMainThreadException 异常处理
- java.lang.RuntimeException: Unable to start activity ComponentInfo....android.os.NetworkOnMainThread
- android.intent.action.MAIN与android.intent.category 决定哪个activity最先执行
- vfp 的主文件MAIN.PRG编译成.EXE可执行文件后,开始运行正常,几天后,不能运行?
- android中多个activity之间不能实现Intent通信
- Android中Activity、Service和线程之间的通信 (2011-09-17 10:14:33)转载▼ 标签: android activity service 线程 之间 通信 it 分
- 主线程中一定不能放耗时操作,必须要开子线程,比如下载文件,不然会不让你拿到输入流--报错显示android.os.NetworkOnMainThreadException
- 关于android主线程不能访问网络异常NetworkOnMainThreadException
- (六十二)Activity的启动模式(转载自http://blog.csdn.net/android_tutor/article/details/6310015)
- 关于android主线程不能访问网络异常NetworkOnMainThreadException
- 关于android主线程不能访问网络异常NetworkOnMainThreadException
- Android 网络通信框架Volley简介(Google IO 2013)(转载自http://blog.csdn.net/t12x3456/article/details/9221611)
- HTTP连接出错:android.os.NetworkOnMainThreadException
- http请求出错 android.os.NetworkOnMainThreadException
- (转载)在Android中使用Handler和Thread线程执行后台操作
- 发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方案(转载http://daydayup1989.iteye.com/blog/784831)
- Android Http错误 NetworkOnMainThreadException