Android_Handler的使用,巨细,慎入

原创 2016年05月31日 10:15:33

Handler是啥子,简而言之就是一个用来更新UI的一套机制,和消息处理的机制;

在看代码前,来捋一捋思路。

一般而言,我们常用的Handler的方法主要就有,post,postDelayed,sendMessage,sendMessageDelayed;

现在在来看看Handler与Looper和MessageQueue之间的关系:

Handler:封装了消息的发送,主要包括了消息发送给谁了

Looper:他的内部包含一个消息队列的的,也就是MessageQueue,也就是,所有的Handler发送的消息都是走向这个消息队列的(sendMessage,这就是证明呀)

他有个重要的方法Looper.Loop:他呢就是一个死循环,不断的从MessageQueue拿消息,如果有消息,那就执行,如果没有消息,那就阻塞、

MessageQueue,根据前面说的,这就是一个消息队列,可以添加消息,并且处理消息。

工作过程:Handler内部会和Looper进行关联,也就是说Handler的内部可以找到Looper ,找到了Looper,也就找到了MessageQueue

,在Handler中发送消息,其实就是想MessageQueue队列中发送消息。

简而言之,Handler负责传送消息,Looper接收Handler传来的消息,MessageQueue就是一堆消息的集合(存储容器)

思路BB完了,现在来看看代码吧

post方法的:

publicclassMainActivityextendsActivity {
      privateTextViewtextView;
      privateHandlerhandler =newHandler();;
      @Override
      protectedvoidonCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
            textView= (TextView) findViewById(R.id.TextView1);
            newThread() {
                  @Override
                  publicvoidrun() {
                        try{
                              Thread.sleep(1000);
                        
                              handler.post(newRunnable() {
                                    @Override
                                    publicvoidrun() {
                                          //这就是更新UI状态,如果不用Handler,那么程序会认为在子线程内部更改UI,程序直接崩溃
                                          textView.setText("Loing for a jab!");
                                    }
                              });
                        }catch(InterruptedException e) {
                              //TODOAuto-generated catch block
                              e.printStackTrace();
                        }
                  }
            }.start();
      }
}

postDelayed:

publicclassMainActivityextendsActivity {
      privateTextViewtextView;
      privateHandlerhandler =newHandler();
      privateImageViewimageView;
      privateintimages[]={R.drawable.tupian1,R.drawable.tupian2,R.drawable.tupian3};
      privateMyRunablemyRunable=newMyRunable();
      //指定图片在哪个当前位子
      privateintindex=0;
      classMyRunableimplementsRunnable{
            @Override
            publicvoidrun() {
                  index++;
                  index=index%3;
                  imageView.setImageResource(images[index]);
                  handler.postDelayed(myRunable, 1000);//传入的对象,和延期的时间
                  System.out.println("线程内");
            }
      }
      @Override
      protectedvoidonCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView= (TextView) findViewById(R.id.TextView1);
            imageView= (ImageView) findViewById(R.id.imageView1);
            handler.postDelayed(myRunable, 1000);
            System.out.println("线程外");
      }
}

sendMessage:

  • 以下是Handler进行int型数据传送的方法
    • 首先就是实例化Handler方法的时候,重写handMessage方法,textView.setText(""+msg.arg1)把要传入的内容显示到text上面
      • privateHandlerhandler =newHandler(){
                    publicvoidhandleMessage(android.os.Message msg) {
                          textView.setText(""+msg.arg1);
                    };
              };
    • 然后就是调用这个方法,传送数据
      •       newThread(){
                          @Override
                          publicvoidrun() {
                                try{
                                      Thread.sleep(1000);
                                      Message message=newMessage();
                                      message.arg1=88;
                                      handler.sendMessage(message);
                                }catch(InterruptedException e) { 
                                      e.printStackTrace();
                                }
                          }

                    }.start();
  • 以下是进行对象数据的传送
    • 实例化
      •     private Handler handler=new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                textView.setText(""+msg.obj);
                Toast.makeText(getApplicationContext(),""+1,1).show();
                return false;
        //       retunrn true;则下面的的handleMessage就不会进行了
            }
        }){
            @Override
            public void handleMessage(Message msg) {
                Toast.makeText(getApplicationContext(),""+2,1).show();

            }
        };
    • 具体函数
      • new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    Message message=handler.obtainMessage();
                    User user=new User();
                    user.age=10;
                    user.name="HAHA";
                    message.obj=user;
                    message.sendToTarget();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
方法扯完了,再来扯点有内涵的,

自定义与线程相关的Handle这个怎么样:

package com.example.administrator.android_handler;


import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;


public class SeconActivity extends Activity {
    private Handler mhandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            Log.d("test","我是主线程:"+Thread.currentThread());
        }
    };
    class MyThread extends Thread{
        public Handler handler;
        @Override
        public void run() {
            //创建一个Looper
            Looper.prepare();
            handler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    Log.d("test","线程:"+Thread.currentThread()); 
                }
            };
            Looper.loop();
        }
    }
    private MyThread thread;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView=new TextView(this);
        textView.setText("hello handle");
        setContentView(textView);


        thread=new MyThread();
        thread.start();
        try {
            thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        thread.handler.sendEmptyMessage(1);
        mhandler.sendEmptyMessage(1);
    }
}

然后即使这个东西HandlerThread:

public class ThreadActivity extends Activity {
    private TextView textView;
    private HandlerThread handlerThread;
    private Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView=new TextView(this);
        textView.setText("handler Thread");
        setContentView(textView);
        handlerThread=new HandlerThread("hander thread");
        handlerThread.start();
        handler=new Handler(handlerThread.getLooper()){
            @Override
            public void handleMessage(Message msg) {
                Log.d("test","线程:"+Thread.currentThread());
                Log.d("test","handlerThread.getLooper():"+handlerThread.getLooper());
            }
        };
        handler.sendEmptyMessage(1);
    }
}

代码如上,这是正确的写法,可以打印出子线程,好的,如果呢,我们把handler=new Handler(handlerThread.getLooper)改成handler=new Handler()的话,那么显示的就会使主线程了。因为他这个就是直接UI里面创建的Handler。我们再改改,handler=new Handler(handler.getLooper)如果改成这样的话呢,那就直接报错了,错误是,空指针,为啥呢,因为你一个线程创建的时候,内部会和Looper进行关联,但是,你的这个handler=new Handler(handler.getLooper),其实就是一个创建的过程,你程序走到这,你Handler还没有Looper进行关联呢,这可不就是一个空指针嘛 。所以这个方法可以防止多线程并发而导致的空指针问题。

主线程和子线程之间的信息交互:

代码如下:

public class FourActivity extends Activity implements View.OnClickListener {
    private Button btSend;
    private Button btStop;
    private HandlerThread thread;
    //这是主线程的创建
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Message message = new Message();
            Log.d("test", "线程:" + Thread.currentThread());
            Log.d("test", "消息内容:" + message);


            threadHandler.sendMessageDelayed(message, 1000);
        }
    };
    private Handler threadHandler;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.four);
        btSend = (Button) findViewById(R.id.bt_send);
        btStop = (Button) findViewById(R.id.bt_stop);
        btSend.setOnClickListener(this);
        btStop.setOnClickListener(this);
        thread = new HandlerThread("handlerThread");
        thread.start();
//子线程的创建
        threadHandler = new Handler(thread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                Message message = new Message();
                handler.sendMessageDelayed(message, 1000);
                Log.d("test", "线程:" + Thread.currentThread());
                Log.d("test", "消息内容:" + message);
            }
        };
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_send:
                handler.sendEmptyMessage(1);
                Log.d("test", "send");
                break;
            case R.id.bt_stop:
                    handler.removeMessages(1);
                
                break;
        }
    }
}

还有就是,我发现这个,循环会一直进行下去,没有办法取消,如果各位亲有发现取消的方法,请告之,谢谢了


版权声明:本文为博主原创文章,未经博主允许不得转载。

深入理解之 Android Handler

一,相关概念 在Android中如果通过用户界面(如button)来来启动线程,然后再线程中的执行代码将状态信息输出到用户界面(如文本框),这时候就会抛出以下的异常信息: 5-12 13:33:0...
  • aaa2832
  • aaa2832
  • 2012年07月22日 23:02
  • 14407

Android HandlerThread 完全解析

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/47079737; 本文出自:【张鸿洋的博客】 1、概述话说最近股市变...
  • lmj623565791
  • lmj623565791
  • 2015年07月27日 09:02
  • 136081

深入研究Android Handler机制

项目终于没那么忙了!闲下来几天,想想应该学点什么,总结点什么。总体上来,要学的东西实在太多了,看了看自己写的代码,结果发现连最基本的消息机制都没有了解清楚,虽然一直在用Handler发消息(Messa...
  • jecons
  • jecons
  • 2014年09月29日 14:43
  • 733

亚人中的中村慎也事件—中村慎也剧场版提前一览

是亚人另一部剧场版的主角,因为被杀死,而引发洪流现象,召唤出一大堆黑色幽灵暴走,第二部剧场版16年5月在日本上映 http://comic.qq.com/a/20160419/044533.htm...
  • hsj1213522415
  • hsj1213522415
  • 2016年12月25日 11:16
  • 2205

吐槽+牢骚(慎入)

今天大扫除,真的是大扫除,好久没这样做卫生了。 陈年旧帐,加在一起,给我们天大的麻烦。不得已,我们用手拿抹布,刷子耍便池,擦地板,擦墙面。全是嘿波垃圾的,恶心到家了。三个人辛勤的同时,有个人却妈的,...
  • d344498093
  • d344498093
  • 2012年06月20日 16:30
  • 829

Android消息机制Handler解析(源码+Demo)

Handler是开发人员在面试过程中最常见的问题之一了,这篇文章将较为全面地对Handler进行解读,包括源码层,以及使用方法。 如果看完文章有疑问,欢迎在评论中一起探讨 基本内容包括: 看完文章...
  • chen_lian_
  • chen_lian_
  • 2016年04月01日 00:25
  • 4578

Android Handler 小结

Android Handler 小结 Handler主要用于异步消息处理。Android中以此作为子线程和主线程通信的桥梁,从而实现ui(主线程)的内容更新。 背景:Android中的主线程主要管理...
  • Pro_Vinny
  • Pro_Vinny
  • 2015年12月11日 10:02
  • 17322

OI流水账(慎入)

一 hello,world!我与计算机的缘分是好久好久之前. 我的妈妈生活在一个艰苦的时代,她用打工赚来的钱坚定地选择了学习计算机 - 所以我应该是出生在电脑桌上的(雾 后来我跟着妈妈学了ps(...
  • hzoi_ztx
  • hzoi_ztx
  • 2015年07月23日 10:16
  • 1111

慎入体制内

体制内的特性决定资源倾斜在上层,因此导致了领导的首要事情是取得他的领导的认可,这样才能要到更多的资源。这样自己才有前途。而非体制内,一个市场化的地方,领导要考虑的是如何激活员工的活力,让员工努力地为他...
  • keshuiyun
  • keshuiyun
  • 2011年04月22日 09:55
  • 1265

Android Handler 源码笔记

Handler:interface Callback -> handleMessage(Message msg) handleMessage(Message msg): 交由子类定制自己的Messag...
  • fyfcauc
  • fyfcauc
  • 2015年10月19日 11:19
  • 302
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android_Handler的使用,巨细,慎入
举报原因:
原因补充:

(最多只允许输入30个字)