Android中进程与线程及如何在子线程中操作UI线程
1. Android进程
一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程。这个线程也是你的应用与界面工具包(android.widget和android.view包中的组件)交互的地方。于是main线程也被称为界面线程。
这种单线程的模式会带来低性能,除非你能正确的优化你的程序。
打个比方:用户触摸屏幕上的一个按钮时的点击事件即向线程中派发事件,比如每一个事件为一辆车。而每一条线程都好像是一条单行线的单车道。这条车道上的车量都排成队行驶至收费口进行事件处理。当处理的事件繁琐,比如在响应用户交互时需执行大量运算,或者像是执行网络连接、数据库请求这样耗时的操作。就会造成拥堵,将会阻止整个界面的响应。当线程被阻塞时,就不能派发事件了。从用户的角度看,程序反应太慢了。甚至更糟的是,如果界面线程被阻塞几秒钟(大5秒钟吧),用户就户抱怨说程序没反应了,用户可能因而退出并删掉你的应用。 此外,Andoid界面不是线程安全的。所以你绝不能在一个工作线程中操作你的界面—你只能在界面线程中管理的你的界面。所以,对于单线程模式有两个简单的规则
1不要阻塞界面线程
2不要在界面线程之外操作界面。
2. 工作线程
由于上述的单线程模式,不要阻塞你的界面线程以使你的应用的界面保持响应是非常重要的,那么如果你有不能很快完成的任务,你应把它们放在另一个线程中执行(后台线程或工作线程)。
例如,下面是的代码是响应click事件,在另外一个线程中从网络获取资源文字并以TextView来显示。
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
第一眼,这看起来能很好的工作,因为它创建了一个新线程来进行网络操作。然而它违反了第二条规则:不要在界面线程之外操作界面—它简单的在工作线程中修改了mTextView。这会导至未定义的异常出现,并且难以调试追踪。
为了能改正这个问题,Android提供了很多从其它线程来操作界面的方法。下面是可用的方法们:
1 Activity.runOnUiThread(Runnable)
2 View.post(Runnable)
3 View.postDelayed(Runnable,long)
4 Handler
5 AsyncTask
现在我们就依次使用这几个方法:
1、Activity.runOnUiThread(Runnable)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- MainActivity.this.runOnUiThread(new Runnable() {
- // 耗时操作
- loadNetWork();
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
- }
- });
2、View.post(Runnable)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.post(new Runnable() {
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
- }
- });
3、View.postDelayed(Runnable,long)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.postDelayed(new Runnable() {
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- }, 10);
- }
- });
- }
- });
4、Handler(子线程调用Handler的handle.sendMessage(msg);
- Handler handle = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- mTextView.setText(来自网络的文字);
- }
- };
- class MyThread extends Thread {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- Message msg = new Message();
- handle.sendMessage(msg);
- super.run();
- }
- }
5、AsyncTask
主线程中:aTask ak = new aTask(); ak.execute();
然后:
- private class aTask extends AsyncTask {
- //后台线程执行时
- @Override
- protected Object doInBackground(Object... params) {
- // 耗时操作
- return loadNetWork();
- }
- //后台线程执行结束后的操作,其中参数result为doInBackground返回的结果
- @Override
- protected void onPostExecute(Object result) {
- super.onPostExecute(result);
- mTextView.setText(result);
- }
- }
Android中进程与线程及如何在子线程中操作UI线程的更多相关文章
- Android 关于操作UI线程
在非UI线程里访问 Android UI toolkit—这个在一个worker线程修改了 View .这会导致不可预期的结果,而且还难以调试. 为了修复这个问题,Android提供了几个方法从非UI ...
- Android 操作UI线程的一些方法
我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...
- 在子jsp页面中调用父jsp中的function或父jsp调用子页面中的function
项目场景: A.jsp中有一个window,window里嵌入了一个<iframe>,通过<iframe>引入了另一个页面B.jsp.在B.jsp中的一个function中需要 ...
- jquery 中选择当前标签下众多相同子标签中的第n个
可以用jquery选择器的:eq选择器或者jquery遍历的eq()方法,下面带那给出ul下第4个li的内容 $("ul li:eq(3)") // 元素的index位置工0开始 ...
- Android 的进程和线程
进程和线程 如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则android系统会为应用程序创建一个包含单个线程的linux进程.默认情况下,同一个应用程序的所有组件都运行在同 ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
- Android中后台线程如何与UI线程交互
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须 ...
- Android UI线程和非UI线程
Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
随机推荐
- POJ3660 Cow Contest —— Floyd 传递闭包
题目链接:http://poj.org/problem?id=3660 Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- POJ1759 Garland —— 二分
题目链接:http://poj.org/problem?id=1759 Garland Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- Java 远程调用之Hessian简例
1. [代码]1.服务接口(Hello.java) package server; public interface Hello { String hello(String name);}2. [代码 ...
- [Selenium] HTML5 中的 Geolocation
在 HTML5 ,新特性 Geolocation 用于定位用户位置信息. 由于用户位置信息是敏感信息,所以需要得到用户允许后,才能让程序通过 API 获取当前用户信息.WebDriver 程序每次重 ...
- Sorting a Three-Valued Sequence
链接 分析:首先我们先对其进行排序,并看排序以后有多少个元素顺序是对的,接着我们看有多少个元素经过一次交换可以得到的,最后剩下的元素就是经过两次交换可以得到的了. /* PROB:sort3 ID:w ...
- 高可用性和PyMongo
High Availability and PyMongo高可用性和PyMongo************************************ PyMongo makes it e ...
- 865C
二分+期望dp 好神奇啊...出题人太神了! 我们发现dp之间的关系不满足是一个dag,那么我们只能用高斯消元,但是由于这里是取最小值,需要取min,也不能用高斯消元,于是我们想出了一个奇妙的方法 我 ...
- ndoejs后台查询数据库返回的值-进行解析
JSON.parse(jsonstr); //可以将json字符串转换成json对象 JSON.stringify(jsonobj); //可以将json对象转换成json对符串
- 实现node端渲染图表的简单方案
实现node端渲染图表的简单方案 这个题目有点小,本篇博客真正谈论的应该是服务端生成图表的简单方案,这里面有两个关键字:服务端 & 简单,我们知道基于js有很多的图表库,知名的如D3.echa ...
- 3.bool布尔值int,str的转化,字符串的常用方法,字符串format,is判断(字符串的数字),for循环
1.bool 布尔值 bool 布尔值 -- 用于条件使用 True 真 False 假 True 真 False 假 print(bool(-10)) # 0 是 False 非0的都是True p ...