android之handler

android中handler的基本使用方法以及运行原理。

最近看mars的android重置版第二季的视频关于handler的讲解,让我对于这个以前知道怎么用,却不是很明白原理的组件的理解瞬间加深了无数倍。mars真的讲的很好,视频真的都蛮不错的。下面我写写自己学习到的知识,以及自己的了解。

  1. handler的基本运行原理
  2. handler怎样从worker thread传输数据到main thread
  3. handler怎样从main thread传输数据到worker thread
  4. handler的post()方法

handler的基本运行原理

为什么我们需要一个handler?我想这是一个最重要的问题,也就是说handler的作用到底是什么?handler主要是用于线程间的通信,那么问题又来了,为什么一个app中需要多个线程,而不是只有一个UI主线程就可以了呢?

假如app中只有一个UI主线程,那么,当需要进行网络连接,网络下载这些等待耗时较长的任务时,android系统就会检测到UI主线程长时间没有响应,就会发出一个 application not response的异常警告,简称ANR问题。所以,在UI主线程中,是要与用户实时交互的,不能出现长时间的等待问题。于是,这些任务必须在worker thread中进行。

然而根据android的设定,UI主线程之外的线程,(除了特别的控件,例如progressbar)不能修改UI里的控件的,这样又出现了新的问题,我们在子线程获得的数据,该如何反应的UI上与用户进行交互?这样,就出现了这个巧妙的组件,handler!

那么,handler到底是如何运行的呢?handler对象首先取出一个消息对象,存入到一个消息队列messagequeue中,然后在另外一端,有一个looper对象,循环的从消息队列中取出消息对象再交给handler去处理。

handler怎样从worker thread传输数据到main thread

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);
//    点击button启动新线程
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                Thread thread = new Mythread();
                thread.start();

            }
        });
        handler = new Myhandler();
    }

//  复写hanlder中的handlerMessage方法,处理从消息队列中得到的消息
    class Myhandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String s = msg.obj.toString();
            System.out.println("在当前线程中"+Thread.currentThread().getName()+"获得来自这个线程的消息"+s);
        }
    }

//  在worker thread中使用handler.obtainMessage()方法得到一个Message对象,再把消息存入message中,发入消息队列
    class Mythread extends Thread{
        @Override
        public void run() {
            Message msg = handler.obtainMessage();
            msg.obj = currentThread().getName();
            handler.sendMessage(msg);
        }
    }
}

通过这个例子,我们可以看到,handlerMessage()方法是运行在主线程中的,而他可以得到来自worker thread的消息,这样,就可以将消息在UI界面更新了。

为什么只是初始化了一个handler对象,就会自动调用他的handleMessage方法?是因为在android.os.Handler类中有一个looper对象,会循环的从消息队列中取出消息,调用handleM而是撒个方法。

handler怎样从main thread传输数据到worker thread

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);

//      每点击一次button,给worker thread 发送一个消息
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
//              在main中使用handler.obtainMessage()方法得到一个Message对象,再把消息存入message中,发入消息队列
                Message msg = handler.obtainMessage();
                msg.obj = Thread.currentThread().getName();
                handler.sendMessage(msg);
            }
        });
        Thread thread = new Mythread();
        thread.start();

    }

//  复写hanlder中的handlerMessage方法,处理得到的消息
    class Myhandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String s = msg.obj.toString();
            System.out.println("在当前线程中"+Thread.currentThread().getName()+"获得来自这个线程的消息"+s);
        }
    }

//  work thread 接受这个消息,并调用handleMeesage()方法处理消息
    class Mythread extends Thread{
        @Override
        public void run() {
//      looper对象的loop方法从消息队列中取出消息,调用handleMeesage()方法处理消息
            Looper.prepare();
            handler = new Myhandler();
            Looper.loop();
        }
    }
}

通过运行结果可以知道,handleMessage()方法运行在worker thread中,这样就可以在worker thread中处理来自主线程的消息,实现了进程间的通信。

handler的post()方法

post方法通过生成一个message,然后把Runnable对象放在message中,再把message放在消息队列中,然后在主线程中取出这个Runnable对象,在主线程中执行。

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);
//      初始化handler,处理得到的Runnable对象
        handler = new Handler();

//      点击按钮执行worker thread
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                Thread thread = new Mythread();
                thread.start();
            }
        });

    }
    class Mythread extends Thread{
        @Override
        public void run() {
//          在worker thread 中初始化一个Runnable对象
            Runnable runnable = new Runnable() {
                public void run() {
//          打印出该Runnable方法执行的线程
                    System.out.println("当前线程名"+Thread.currentThread().getName());
                }
            };
//          post该Runnable对象
            handler.post(runnable);
        }
    }
}

最后的结果,是这个Runnable对象执行在main线程中。有了post()方法,我们可以直接在worker thread中先生成一个Runnable对象,然后在其中写上更新UI的代码,直接用post方法即可更新UI。

时间: 2024-08-03 11:04:01

android之handler的相关文章

Android的Handler深入解析

1.概述 前面写过一篇文章<Android中的消息机制>简单分析了异步消息机制,本文将深入解读Handler的原理. 2.基本概念 单线程模型中的Message.Handler.Message Queue.Looper之间的关系: Handler获取当前线程的Looper对象,Looper用来从存放Message的MessageQueue中取出Message,再由Handler进行Message的分发和处理. (1)Message Queue(消息队列) 用来存放通过Handler发布的消息,

android之handler机制深入解析

一.android中需要另开线程处理耗时.网络的任务,但是有必须要在UI线程中修改组件.这样做是为了: ①只能在UI线程中修改组件,避免了多线程造成组件显示混乱 ②不使用加锁策略是为了提高性能,因为android中经常使用多线程. handler就是为了解决在多个线程之间的通信问题. 二.基本使用: 1 package com.dqxst.first.multithread; 2 3 import android.app.Activity; 4 import android.os.Bundle;

Android Thread Handler UIHandler demos

extends:http://blog.csdn.net/superjunjin/article/details/7540064 序效果:为了显示如何用message传值的简单例子 例1,点击按钮,持续显示当前系统时间(bundle传值,耗时,效率低) 例2,点击按钮,progressbar持续前进(message方法传值,效率高,但只能传整型int和对象object) 例1,主activity  package com.song; import java.text.SimpleDateForm

Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主要研究Handler的消息发送. 包含主线程往子线程发送消息,子线程之间互相发送消息. 一.主线程向子线程发送消息. 实现过程比較简单: 主线程发送消息到异步线程.异步线程接收到消息后在再发送一条消息给主线程. 1. 初始化主线程的Handler,用来接收子线程的消息. 2. 启动异步线程.在异步线

深入解析Android中Handler消息机制

Android提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange).Handler消息机制可以说是Android系统中最重要部分之一,所以,本篇博客我们就来深入解析Android中Handler消息机制. Handler的简单使用 为什么系统不允许子线程更新UI 因为的UI控件不是线程安全的. 如果在多线程中并发访问可能会导致UI控件处于不可预期的状态,那为什么不对UI控件的访

Android 测试Handler的基本使用

package com.sherlock.app_handler; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import andro

Android之Handler用法总结

方法一:(java习惯,在android平台开发时这样是不行的,因为它违背了单线程模型) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 可以实现功能,刷新UI界面.但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 方法二

Android - This Handler class should be static or leaks might occur.

今天学习了使用 HTTP协议,从Android客户端往Tomcat服务器端以GET发送请求,途中无意中发现自己写的Handler类被Android提示:This Handler class should be static or leaks might occur. 往google上type,发现很多网友都做了解释,也感触颇深,编译器的提示,有时真的要留意,这对自己学习也有很大的帮助. 虽然多了几行代码,但为了实用,我就上贴自己实际点的例子,Activity: package spt.http.

Android的Handler及looper

看了这么多的文章,终于看懂了. 参考文献: [1]android developer handler [2]Android中Handler作用 [3] Android Thread Looper Handler 关系 [4]android的消息处理机制(图+源码分析)--Looper,Handler,Message 1.从定义上理解Handler 首先有一下参考文献[1]中的一句英文句子来说明下: A Handler allows you to send and process Message 

(Android review)handler的基本使用

一.基本知识点 1.Intent intent = new Intent();//打开浏览器的intent.setAction(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com")); 2.SystemClock.sleep(20000);//睡眠20秒,用来掩饰想赢一场 3.耗时的操作都应该子线程中做联网获取数据大文件的拷贝都需要放置在子线程来操作 onCreate()  按钮点击回调事件.对于显示的