Android handler 详解(面试必问)

所属分类: 软件编程 / Android 阅读数: 1150
收藏 0 赞 0 分享

handler在Android中被称为“消息处理者”,在多线程中比较常用。

Handler为Android提供了一种异步消息处理机制,当向消息队列中发送消息 (sendMessage)后就立即返回,而从消息队列中读取消息时会阻塞,其中从消息队列中读取消息时会执行Handler中的public void handleMessage(Message msg) 方法,因此在创建Handler时应该使用匿名内部类重写该方法,在该方法中写上读取到消息后的操作,使用Handler的 obtainMessage() 来获得消息对象。

  Handler与线程的关系:

  使用Handler的post方法将Runnable对象放到Handler的线程队列中后,该Runnable的执行其实并未单独开启线程,而是仍然在当前Activity线程中执行的,Handler只是调用了Runnable对象的run方法。

  Bundle是什么:

  Bundle是一个特殊的map,它是传递信息的工具,它的键只能是string类型,而且值也只能是常见的基本数据类型。

handler内部实现原理

handler实现机制:

1,Message对象,表示要传递的一个消息,内部使用链表数据结构实现一个消息池,用于重复利用,
避免大量创建消息对象,造成内存浪费
2,MessageQueue对象,存放消息对象的消息队列,先进先出原则
3,Looper对象负责管理当前线程的消息队列
4,handler对象负责把消息push到消息队列中,以及接收Looper从消息队列中取出的消息

handler的内存泄露问题(activity已经退出,而handler没有退出,这样就可能导致内存泄露)

1,定义一个内部类时,会默认拥有外部类对象的引用,所以建议使用内部类时,最好定义一个静态内部类
2,引用的强弱:强引用→软引用→弱引用

下面用获取网络图片代码说明一下handler基本使用

package com.example.uri;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;
/**
* 
* 访问网络的操作,必须放在工作线程中完成
*
*/
public class MainActivity extends Activity {
private static final int LOADSUCCESS=0x1;
private static ImageView iv;
private final myhandler handler=new myhandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv=(ImageView) findViewById(R.id.imageView1);
}
private static class myhandler extends Handler{
private final WeakReference<MainActivity> weakReference;
public myhandler(MainActivity mainActivity){
weakReference=new WeakReference<MainActivity>(mainActivity);
}
public void handleMessage(Message msg) {
MainActivity mainActivity=weakReference.get();
if(mainActivity!=null){
switch (msg.what) {
case LOADSUCCESS:
MainActivity.iv.setImageBitmap((Bitmap) msg.obj);
break;
}
}
}
}
public void geturl(View v){
/*Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
startActivity(intent); */
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url=new URL("http://img2.3lian.com/img2007/10/28/123.jpg");
InputStream in=url.openStream();
Bitmap bitmap=BitmapFactory.decodeStream(in);
Message message= handler.obtainMessage(LOADSUCCESS, bitmap);
handler.sendMessage(message);
} catch (MalformedURLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}).start();
}
}

如何让Handler执行Runnable时打开新的线程:

  1、首先生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供
  HandlerThread handlerThread = new HandlerThread("handler_thread");

  2、在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();
  handlerThread。start();

  3、根据这个HandlerThread对象得到其中的Looper对象。

  4、创建自定义的继承于Handler类的子类,其中实现一个参数为Looper对象的构造方法,方法内容调用父类的构造函数即可。

  5、使用第三步得到的Looper对象创建自定义的Handler子类的对象,再将消息(Message)发送到该Handler的消息队列中,Handler复写的handleMessage()将会执行来处理消息队列中的消息。

以上给大家详细介绍了Android handler 相关知识,希望对大家有所帮助!

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多