Android中的Handler, Looper, MessageQueue和Thread
来源:互联网 发布:win8 装 ubuntu 编辑:程序博客网 时间:2024/05/29 14:13
直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,错 误android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。
在Android开发中,为了UI线程能及时响应需要避免在其中执行耗时操作,以防止界面假死甚至ANR。我们一般把耗时操作如下载,查询放在一个单独的线程中。这之后再将结果更新到UI界面。android平台在非UI线程中更新界面大致有以下几种方式
Handler的处理过程运行在创建Handler的线程里
一个Looper对应一个MessageQueue
一个线程对应一个Looper
一个Looper可以对应多个Handler
子线程中修改UI的方法
要想修改UI都必须在主线程中去做,我们不能直接在UI线程中去创建子线程,要利用消息机制:handler.
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。
在Android开发中,为了UI线程能及时响应需要避免在其中执行耗时操作,以防止界面假死甚至ANR。我们一般把耗时操作如下载,查询放在一个单独的线程中。这之后再将结果更新到UI界面。android平台在非UI线程中更新界面大致有以下几种方式
Handler的处理过程运行在创建Handler的线程里
一个Looper对应一个MessageQueue
一个线程对应一个Looper
一个Looper可以对应多个Handler
不确定当前线程时,更新UI时尽量调用post方法
<span style="color:#333333;">public class MainActivity extends Activity {private Button button;private Handler handler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);handler = new TimerHandler();WorkerThread wt = new WorkerThread();wt.start();}class WorkerThread extends Thread{@Overridepublic void run(){while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//创建消息Message msg = handler.obtainMessage();msg.arg1 = 10;msg.arg2 = 20;msg.obj = "zhangsan";//发送消息handler.sendMessage(msg);}}}class TimerHandler extends Handler{@Overridepublic void handleMessage(Message msg) {//接收消息,此消息可以使对象int i = msg.arg1;int j = msg.arg2;String s = (String)msg.obj;Log.d("Handler", "收到消息:arg1:" + i +",arg2:" + j + ",s:" + s);}}}</span>一些耗时间的操作放在线程中去,通过Handler传递消息
public class MainActivity extends Activity {private TextView textView;private Button button;private Handler handler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);handler = new NetworkHandler();textView = (TextView)findViewById(R.id.textViewId);button = (Button)findViewById(R.id.buttonId);button.setOnClickListener(new ButtonListener());}class ButtonListener implements OnClickListener{@Overridepublic void onClick(View v) {NetworkThread nt = new NetworkThread();nt.start();}}class NetworkThread extends Thread{@Overridepublic void run(){String url = "http://192.168.105.129:8081/data.html";Log.d("Handler02", "准备访问网路");//得到从网上下载的数据String data = getStringFromNetwork(url);//textView.setText(data);该行代码引起错误的原因是,不能够在Worker Thread当中修改控件的值//把数据放到handler中要用handler.obtainMessage();Message msg = handler.obtainMessage();msg.obj = data;handler.sendMessage(msg);}}class NetworkHandler extends Handler{@Overridepublic void handleMessage(Message msg){//得到handler中数据把它赋给dataString data = (String)msg.obj;textView.setText(data);}}//新建一个类,类型是String urlpublic String getStringFromNetwork(String url){String result = ""; //建个Http客户端访问网络下载数据HttpClient httpClient = new DefaultHttpClient();HttpGet httpGet = new HttpGet(url);try {HttpResponse response = httpClient.execute(httpGet);if(response.getStatusLine().getStatusCode() == 200){HttpEntity entity = response.getEntity();//连接已建立数据在entity中从entity中开始读数据BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));result = reader.readLine();Log.d("Handler02", "访问网络的结果是" + result);return result;}} catch (Exception e) {e.printStackTrace();}return result;}}
Looper的用法
class WorkerThread extends Thread{@Overridepublic void run(){//生成Looper对象,该对象与当前线程对象组成了对应关系Looper.prepare();//生成Handler对象,并将其与刚刚生成Looper对象建立对应关系handler = new Handler(){@Overridepublic void handleMessage(Message msg){Log.d("Handler", "收到来自主线程的消息");}};Looper.loop();}}
子线程中修改UI的方法
class WorkThread extends Thread{int i = 0 ;@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}i++;handler.post(new Runnable() {@Overridepublic void run() {textView.setText(i + "");}});}
0 0
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- 【开发手记二】:各有千秋:搭建Linaro Ubuntu与搭建嵌入式Linux系统
- duilib corner属性的贴图技巧——让图片自动贴到控件的的某一边或者一角并自适应控件的大小
- Javascript使用技巧-提高工作效率
- IIS典型错误解决大全
- wpf利用动画实现图形变化产生3d效果
- Android中的Handler, Looper, MessageQueue和Thread
- 一个菜鸟程序员的文学情怀
- maven基础学习-父pom文件的使用(七)
- MFC 滑动条实现
- 【开发手记三】一步一坑:UART和GPIO协同控制LED
- HDU 1495 非常可乐(隐式图搜索)
- zero
- 【2014】【辛星】【php】【秋季】【5】其他的变量运算符
- 2014年8月9日至2014年8月29日,剩4300小时