android handler 广播,Android handler机制

为什么要使用Handler:

1. 因为在android中有很多的UI控件,通常会通过UI控件来控制操作的数据,如果处理的数据很多,这种情况下需要将处理操作放到线程中,而创建后的子线程是不能主动更新UI的,需要使用Handler机制返回UI主线程;

2. UI的绘制不是所有都需要动画来实现,简单的东西可以通过handler来做,比如跑马灯的绘制,handler的定时消息,以便在消息处理中进行UI的滚动绘制

API说明如下:

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

翻译:

Handler 允许你发送和处理Message(消息)和与一个线程相关的MessageQueue(消息队列)的Runnable对象,每一个Handler实例都与 一个单独的线程和该线程的消息队列相关。当你创建一个新的Handler,它被绑定到创建它的线程/消息队列线程中。从这一点上来说,它将传递消息和 runnable对象,并且执行他们,因为他们来自于消息队列中

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

翻译:

Handler有两个主要用法:1、安排messages和runnables在将来的某些点上执行;2、排列一个将来执行的动作在一个不同的线程中

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).

翻译:

安排messages是通过 post(Runnable), postAtTime(Runnable, long),postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)方法来完成的。The post versions允许你排列Runnable对象被接收到的消息队列所调用;the sendMessage versions允许您排列一个包含了大量将被Handler的handleMessage(Message)方法处理的数据的Message对象(需要 你实现Handler的一个子类

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.

翻译:

当一个进程在 你的应用中被创建,它的主线程致力于运行一个负责管理顶级应用程序对象(如:活动、广播接收器等)和他们创建的任何windows的消息队列。您可以创建 你自己的线程,通过Handler与主应用线程进行交互。这样都在之前通过调用的同一个post和sendMessage方法实现的,但是来自你的新线 程。给定的Runnable或Message将被安排在Handler的message队列,并在适当的时候进行处理。

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.

翻译:

当 一个进程在你的应用中被创建,它的主线程致力于运行一个负责管理顶级应用程序对象(如:活动、广播接收器等)和他们创建的任何windows的消息队列。 您可以创建你自己的线程,通过Handler与主应用线程进行交互。这样都在之前通过调用的同一个post和sendMessage方法实现的,但是来自 你的新线程。给定的Runnable或Message将被安排在Handler的message队列,并在适当的时候进行处理。

总结:在使用Handler过程中,通常也要使用Message,Looper(如果Handler在主线程中创建,则不需要写,Looper会自动创建),Thread/Runnable

注意:1. 一个Handler实例对应一个MessageQueue,对应一个线程

2. 创建Message的时候API中推荐使用从消息队列池中取,如果没有,消息队列池会自动创建一个Message,如果有,从消息队列池取出一个Message

3. Handler的内存泄漏问题(如下):

handler1-300x110.jpg

为什么会出现这种情况:当Activity结束后,在 Message queue 处理这个Message之前,它会持续存活着。这个Message持有Handler的引用,而Handler有持有Activity的引用,这个Activity所有的资源,在这个消息处理之前都不能也不会被回收,所以发生了内存泄露。

使用静态的内部类,不会持有当前对象的引用

handler2-300x105.jpg

下面给出一个简单的Handler实例:(每隔几秒在列表中添加一个Item)

1-188x300.jpg

package com.example.handler;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.app.Activity;

import android.util.Log;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

public class MainActivity extends Activity implements OnClickListener{

private Runnable runnable;

private ListView listView;

private Button button;

private String TAG = "MainActivity";

private static ArrayAdapter adapter;

private static Handler handler = new Handler(){

//从消息队列中取出消息msg

@Override

public void handleMessage(Message msg) {

if(msg.what==1){

int arg1 = msg.arg1;

String strObj = (String) msg.obj;

//列表中加入Item

adapter.insert(strObj, arg1);

//更新ListView

adapter.notifyDataSetChanged();

}else if(msg.what==2){

adapter.clear();

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

listView = (ListView) findViewById(R.id.listview);

button.setOnClickListener(this);

adapter = new ArrayAdapter(MainActivity.this,

R.layout.list, R.id.textview);

listView.setAdapter(adapter);

runnable = new Runnable() {

public void run() {

int count = 0;

while(count<15){

try {

Thread.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

//创建Message时,从消息池中取,如果没有,消息池会创建;如果有,从消息池中取

Message message = Message.obtain();

//message arg1,arg2为int类型的参数

message.arg1 = count++;

//message可以携带数据

message.obj = "你好"+count;

//what属性作为判断标志

message.what = 1;

//发送message

handler.sendMessage(message);

}

Message msg = Message.obtain();

msg.what = 2;

handler.sendMessage(msg);

}

};

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.button:

new Thread(runnable).start();

break;

default:

break;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值