2023年7月7日发(作者:)
Android消息处理机制(Handler与Message)⼀、handler的使⽤场景为么会有handler?⼆、handler的消息处理机制在Android中提供了⼀种异步回调机制Handler,使⽤它,我们可以在完成⼀个很长时间的任务后做出相应的通知。 -UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化⼀个Looper对象,同时也会创建⼀个与其关联的MessageQueue;-Handler:作⽤就是发送与处理信息,如果希望Handler正常⼯作,在当前线程中要有⼀个Looper对象-Message:Handler接收与处理的消息对象-MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建⼀个与之关联的MessageQueue;-Looper:每个线程只能够有⼀个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!通俗⼀点讲:当我们的⼦线程想修改Activity中的UI组件时,我们可以新建⼀个Handler对象,通过这个对象向主线程发送信息;⽽我们发送的信息会先到主线程的MessageQueue进⾏等待,由Looper按先⼊先出顺序取出,再根据message对象的what属性分发给对应的Handler进⾏处理!三、Handler的相关⽅法在使⽤android的消息的处理机制的时候:⼀般是有两种⼿段,1、该message⾃⼰绑定到⽬标handler后,⾃⾏进⼊messageQueue,等待handler接受处理。Message⽅法:public static Messageobtain(Handler h, int what, int arg1, int arg2, Object obj) ,通过该⽅法可以获得⼀个消息:Message message =(handler, 33, 2, 3, “hello”);发送消息的⽅式,有⼀点将⾃⼰绑定好了被发射的感觉,Target(); —被动(意会)2、handler主动设置要发送的消息的各个属性值:arg1,arg2,obj,what。⽅法:public final Message obtainMessage(int what,int arg1, int arg2, Object obj) 通过该⽅法也可以获得⼀个消息:⽐如Message message = Message(3, 1, 2,“java”);然后将设置好的消息,由handler发送出去:ssage(message);----主动(⾃⼰意会的)。下⾯⼗⼏个常⽤⽅法:void handleMessage(Message msg):处理消息的⽅法,使⽤handleMessage去处理消息,⾥⾯的参数Message msg既是在messageQueue⾥⾯取出的消息message~sendEmptyMessage(int what):发送空消息sendEmptyMessageDelayed(int what,long delayMillis):指定延时多少毫秒后发送空信息sendMessage(Message msg):⽴即发送信息sendMessageDelayed(Message msg):指定延时多少毫秒后发送信息final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 如果是参数为(int what,Object object):除了判断what属性,还需要判断Object属性是否为指定对象的消息// ⾸先是被动⽅式:import ;import r;import e;import ty;import ;import ;/**此处重点熟悉message的属性,将message绑定到⽬标handler,然后直接使⽤message的⽅法将消息发送,被动发送。@author*/// 在安卓开发中是绝对不能使⽤UI主线程去访问⽹络 的,⼀定是要开⼀条新的线程去访问然后把结果返回public class MainActivity extends Activity {private Button button;// handler对象,⽤来接收消息~private Handler handler = new Handler() {@Overridepublic void handleMessage(e msg) { //这个是发送过来的消息// 处理从⼦线程发送过来的消息int arg1 = 1; //获取消息携带的属性值int arg2 = 2;int what = ;Object result = ;n("-arg1—>>" + arg1);n("-arg2—>>" + arg2);n("-what—>>" + what);n("-result—>>" + result);Bundle bundle = a(); // ⽤来获取消息⾥⾯的bundle数据n("-getData—>>"+ ingArray(“strs”).length);};};@Overrideprotected void onCreate(Bundle savedInstanceState) {te(savedInstanceState);setContentView(ty_main);button = (Button) findViewById(1);lickListener(new kListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub// 启动⼀个⼦线程new Thread(new MyThread()).start(); //⼀定要在这⾥⾯启动!}});}public class MyThread implements Runnable {@Overridepublic void run() { //run⽅法⾥⾯写要发送的消息对象,并对消息携带的信息进⾏定义!!// TODO Auto-generated method stub// 第⼀种⽅式:获取消息// Message message = ();// = 1;// 1 = 2;// 2 = 3;// = “jack”;// ssage(message);// 第⼆种⽅式// Message message = (handler);// = 1;// 1 = 2;// 2 = 3;// = “jack”;// (message);// //此时在构造⽅法⾥⾯已经将message的target绑定了handler不需要再次发送了。// Target();// 第三种⽅式,和上⾯是没有区别的。。// Message message = (handler, 33);// 1 = 2;// 2 = 3;// = “jack”;// Target();// 第4种⽅式这⼏种⽅式都是⼤同⼩异,只不过是内部封装了⽽已,使⽤的时候根据实际需要就可以了。Message message = (handler, 33, 2, 3, “hello”);Bundle data = new Bundle(); //message也可以携带复杂⼀点的数据⽐如:bundle对象。ingArray(“strs”, new String[] { “c”, “c++”, “java” });a(data);Target(); // 不可忘!}}}//handler的主动发送消息import ;import r;import e;import Clock;import ty;import ;import ;import kListener;import ;/**此处主要是使⽤handler的主动抓取、发送message功能!在messaQequue⾥⾯@author15 **/public class MainActivity extends Activity implements OnClickListener {private Button button, button2;// Handler可以接受发送消息,从消息队列中提取消息⽤于更新UI,这⾥都没有对UI进⾏操作,主要是介绍如何定义⾃⼰的message如何发送这个message,最后将会给⼀个demoprivate Handler handler = new Handler() {@Overridepublic void handleMessage(e msg) {n("-arg1—>" + 1);n("-arg2—>" + 2);n("-what—>" + );n("-obj—>" + );};};@Overrideprotected void onCreate(Bundle savedInstanceState) {te(savedInstanceState);setContentView(ty_main);button = (Button) findViewById(1);button2 = (Button) findViewById(2);lickListener(this);lickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (()) {case 1:new Thread(new Runnable() { //使⽤匿名内部类的⽅式,这个⽆难点吧。。。@Overridepublic void run() {// TODO Auto-generated method stub// handler发送消息的第⼀种⽅式// ptyMessage(3);// handler发送消息的第⼆种⽅式,第⼆个参数是指定在指定的时间上发送消息,这个是确定的某个时间!// 可以通过获取当前的系统时间后Millis()再加上某个时间,如果给出的时间⼩于当前时间则⽴即发送,亲测 //⽽且感觉这个功能很bug的,在特定的时间,需要我们⼈为的去计算:Millis()+myTime(这个是你想在多少毫秒后启动的毫秒值)// ptyMessageAtTime(3, X+3000);// handler发送消息的第三种⽅式,这个效果是在3000毫秒后延迟。// ptyMessageDelayed(3, 3000);// handler发送消息的第四种⽅式// Message message = (); //这个是使⽤message被动得到// Message message = Message(); //// handler的主动获取消息,在源码⽅⾯⼀样!⽆区别。// 1 = 1;// 2 = 2;// = “java”;// = 4;// 使⽤handler发送消息的第五种⽅式,原理都是⼀样的~ //我最习惯还是message⾃⼰搞⾃⼰的事情别去⼲发送的活,message需要携带的属性由他⾃⼰搞,剩下的发送接收处理的体⼒劳动由handler搞。Message message = Message(3, 1, 2, “java”);ssage(message);}}).start(); //记得启动break;case 2:// 第⼆个按钮使⽤post⽅式发送消息,该⽅法需要⼀个runnable的实例,使⽤匿名内部类的⽅式实现。// 直接使⽤⼀个匿名内部类Runnable来执⾏1.获取消息对象;2.发送消息对象。换汤不换药,通过看源码也可以知道背后的实现都是⼀个道理。(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubMessage message = Message(23, 21, 22, “postMessage”);ssage(message);}});break;}}}//具体应⽤handler来更新UIimport rayOutputStream;import ption;import tream;import tity;import sponse;import ient;import t;import tHttpClient;import Utils;import ;import r;import e;import ty;import ssDialog;import Factory;import ;import ;import iew;// 标准的写法private Handler handler = new Handler() {// 使⽤handleMessage去处理消息!!,⾥⾯的参数Message msg既是发送过来的参数~@Overridepublic void handleMessage(e msg) {//// 在此接受发送过来的消息<—msgbyte[] data = (byte[]) ; //转型// 将接受过来的数据赋值给geBitmap(ByteArray(data, 0,));// 标记~数据发送已经结束了?,此处有由代码的逻辑顺序来决定的,if ( == IS_FINSIH) {s();}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {te(savedInstanceState);setContentView(ty_main);imageView = (ImageView) findViewById(iew1);dialog = new ProgressDialog(this);le(“提⽰”);sage(“正在下载,请稍等…”);celable(false);button = (Button) findViewById(1);lickListener(new kListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub// 开启线程new Thread(new MyThread()).start();(); // 显⽰对话框他会直接先显⽰出来这个是位于主线程⾥⾯的。与thread互不影响。}});}// 避免在UI主线程⾥⾯更新数据public class MyThread implements Runnable {@Overridepublic void run() {// TODO Auto-generated method stub// 使⽤http完成⽹络下载的操作HttpClient httpClient = new DefaultHttpClient();HttpGet httpGet = new HttpGet(image_path);HttpResponse httpResponse = null;//下⾯是我在http的使⽤过程中总结的⼀些⼼得,对于http没有经验,有错请指出。。。/** 这种⽅式获取响应内容的实体~entity中的流对象!不建议使⽤了。⽐较⿇烦, InputStream inputStream* =null; inputStream = ity().getContent();* 然后将该inputStream写⼊到ByteArrayOutputStream,然后该内存缓冲流可以转为字节数组byte[]=* Array();*/// 使⽤http新的就是通过httpclient执⾏要执⾏的get/或者post⽅法然后获取服务端响应过来的实体对象entity;// 然后从该entity中获取需要的数据⽐如inputstream/⽂件的长度等。。。⼀般我们的最终⽬的都是获取⼀个字节数组!byte[]只有⼆进制的数据才是数据的终极形态!// 在使⽤的时候为了⽅便操作有⼀个⼯具类可以帮助我们简单的获取⼆进制数组try {httpResponse = e(httpGet);// client执⾏请求~典型的⾯对对象:客户端对象取执⾏请求的⽅法,获得返回的内容对象。通过⼯具来解析内容// 判断连接是否正常if (tusLine().getStatusCode() == 200) {HttpEntity entity = ity(); //获取响应头的实体内容// 使⽤EntityUtilsbyte[] data = Array(entity);// 到了这⾥就是需要把我们的数据发送给UI主线程,⼆进制数组是最好的发送对象// Message message = new Message() 该⽅法是创建⽽不是在的当前的线程池取出。Message message = (); = data; = IS_FINSIH; // 结束标志位ssage(message); // 将数据发送过去~}} catch (IOException e) {// TODO Auto-generated catch tackTrace();}}}}
发布者:admin,转转请注明出处:http://www.yc00.com/web/1688674457a161648.html
评论列表(0条)