Android的Handler机制的一些理解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android的Handler机制的一些理解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5805字,纯文字阅读大概需要9分钟。
内容图文
Handler是什么
在Android中表示一种消息处理机制或者叫消息处理方法,用来循环处理应用程序主线程各种消息,比如UI的更新,按键、触摸消息事件等。
为什么Android要用Handler机制
Android应用程序启动时,系统会创建一个主线程,负责与UI组件(widget、view)进行交互,比如控制UI界面界面显示、更新等;分发事件给UI界面处理,比如按键事件、触摸事件、屏幕绘图事件等,因此,Android主线程也称为UI线程。
由此可知,UI线程只能处理一些简单的、短暂的操作,如果要执行繁重的任务或者耗时很长的操作,比如访问网络、数据库、下载等,这种单线程模型会导致线程运行性能大大降低,甚至阻塞UI线程,如果被阻塞超过5秒,系统会提示应用程序无相应对话框,缩写为ANR,导致退出整个应用程序或者短暂杀死应用程序。
除此之外,单线程模型的UI主线程也是不安全的,会造成不可确定的结果。线程不安全简单理解为:多线程访问资源时,有可能出现多个线程先后更改数据造成数据不一致。比如,A工作线程(也称为子线程)访问某个公共UI资源,B工作线程在某个时候也访问了该公共资源,当B线程正访问时,公共资源的属性已经被A改变了,这样B得到的结果不是所需要的的,造成了数据不一致的混乱情况。
线程安全简单理解为:当一个线程访问功能资源时,对该资源进程了保护,比如加了锁机制,当前线程在没有访问结束释放锁之前,其他线程只能等待直到释放锁才能访问,这样的线程就是安全的。
基于以上原因,Android的单线程模型必须遵守两个规则:
1. 不要阻塞UI线程;
2. 不要在UI线程之外访问UI组件,即不能在子线程访问UI组件,只能在UI线程访问。
因此,Android系统将大部分耗时、繁重任务交给子线程完成,不会在主线程中完成,解决了第一个难题;同时,Android只允许主线程更新UI界面,子线程处理后的结果无法和主线程交互,即无法直接访问主线程,这就要用到Handler机制来解决此问题。基于Handler机制,在子线程先获得Handler对象,该对象将数据发送到主线程消息队列,主线程通过Loop循环获取消息交给Handler处理。
案例用法
下面两个案例都实现一个定时器,每隔一秒显示数字0-9
案例1:sendMenssage方法更新UI界面
1 package com.example.testhandler; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Message; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button; 10 import android.widget.TextView; 11 12 public class TestHandlerActivity extends Activity { 1314protectedstaticfinal String TAG = "TestHandlerActivity"; 15private Button sendButton; 16private TextView displayText; 1718 Handler mHandler = new Handler() { 1920 @Override 21publicvoid handleMessage(Message msg) { 22// TODO Auto-generated method stub23if (msg.what == 99) { 24int i = msg.getData().getInt("displayKey"); 25 displayText.setText(i + ""); 26 } 27super.handleMessage(msg); 28 } 2930 }; 31private Button exitButton; 3233 @Override 34protectedvoid onCreate(Bundle savedInstanceState) { 35super.onCreate(savedInstanceState); 36 setContentView(R.layout.activity_main); 37 initViews(); 38 } 3940privatevoid initViews() { 4142 displayText = (TextView) findViewById(R.id.display_text); 43 sendButton = (Button) findViewById(R.id.send_button); 44 sendButton.setOnClickListener(buttonOnClickListener); 45 exitButton = (Button) findViewById(R.id.exit_button); 46 exitButton.setOnClickListener(buttonOnClickListener); 47 } 4849 OnClickListener buttonOnClickListener = new OnClickListener() { 5051 @Override 52publicvoid onClick(View v) { 53// TODO Auto-generated method stub54if (v.getId() == R.id.send_button) { 55new Thread(new WorkRunnable()).start(); 56 } elseif (v.getId() == R.id.exit_button) { 57 finish(); 58 } 59 } 6061 }; 6263class WorkRunnable implements Runnable { 64 @Override 65publicvoid run() { 66// TODO Auto-generated method stub67int i = 0; 68while (i < 10) { 69 Message msg = mHandler.obtainMessage(99); 70 Bundle bundle = new Bundle(); 71 bundle.putInt("displayKey", i); 72 msg.setData(bundle); 73 mHandler.sendMessage(msg); 74try { 75 Thread.sleep(1000); 76 } catch (InterruptedException e) { 77// TODO Auto-generated catch block78 e.printStackTrace(); 79 } 80 i++; 81 } 82 } 83 } 8485 @Override 86protectedvoid onDestroy() { 87// TODO Auto-generated method stub88if (mHandler != null) { 89if (mHandler.hasMessages(99)) { 90 mHandler.removeMessages(99); 91 } 92 mHandler = null; 93 } 94super.onDestroy(); 95 } 96 }
WorkRunnable的run方法中进行了耗时操作,要把结果反馈给UI,需要Handler发送消息给UI线程,在Handler的handleMessage对消息进行处理
案例2: postDelayed更新UI
1 package com.example.postdelaydemo; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.util.Log; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button; 10 import android.widget.TextView; 11 12 public class PostDelayActivity extends Activity { 13protectedstaticfinal String TAG = "PostDelayActivity"; 14private Button sendButton; 15private TextView displayText; 16private Button exitButton; 17 Handler mHandler = new Handler(); 1819 @Override 20protectedvoid onCreate(Bundle savedInstanceState) { 21super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_main); 23 initViews(); 24 } 2526privatevoid initViews() { 27 displayText = (TextView) findViewById(R.id.display_text); 28 sendButton = (Button) findViewById(R.id.send_button); 29 sendButton.setOnClickListener(buttonOnClickListener); 30 exitButton = (Button) findViewById(R.id.exit_button); 31 exitButton.setOnClickListener(buttonOnClickListener); 32 } 3334 OnClickListener buttonOnClickListener = new OnClickListener() { 35 @Override 36publicvoid onClick(View v) { 37// TODO Auto-generated method stub38if (v.getId() == R.id.send_button) { 39 mHandler.postDelayed(new PostDelayRunnable(), 1000); 40 } elseif (v.getId() == R.id.exit_button) { 41 finish(); 42 } 43 } 44 }; 4546class PostDelayRunnable implements Runnable { 47int i = 0; 4849 @Override 50publicvoid run() { 51// TODO Auto-generated method stub52if (i >= 10) { 53 mHandler.removeCallbacks(this); 54 } else { 55 displayText.setText(getResources().getString( 56 R.string.display_label) 57 + i); 58 mHandler.postDelayed(this, 1000); 59 } 60 i++; 61 } 62 } 6364 @Override 65protectedvoid onDestroy() { 66// TODO Auto-generated method stub67if (mHandler != null) { 68 mHandler = null; 69 } 70super.onDestroy(); 71 } 72 }
postDelayed方法把runnable对象作为消息放到队列中等待执行,run方法中就是具体执行过程。
msg.target是Handler的一个对象引用,handler对象发送消息暂存到消息队列,Looper取出消息分发给相应的handler处理。
Handler.post(new Runnable())和sendmessage(msg)区别
(1) 都是把消息放到消息队列等待执行,前者放的是一个runnable对象,后者是一个message对象;
(2) 前者最终还是会转化成sendMessage,只不过最终的处理方式不一样,前者会执行runnable的run方法;后者可以被安排到线程中执行。
(3) 两者本质没有区别,都可以更新UI,区别在于是否易于维护等。
HandlerThread是什么
HandlerThread继承了Thread,是一个包含有looper的线程类。正常情况下,除了主线程,工作线程是没有looper的,但是为了像主线程那样也能循环处理消息,Android也自定义一个包含looper的工作线程——HandlerThread类。
啊啊啊啊啊啊啊啊西吧太菜了,源码看不懂
原文:http://www.cnblogs.com/tero/p/5304118.html
内容总结
以上是互联网集市为您收集整理的Android的Handler机制的一些理解全部内容,希望文章能够帮你解决Android的Handler机制的一些理解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。