android handler面试,Android handler 详解(面试必问)

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内部实现原理

cc09ab22f9cd5688d381dd7b2e609e2e.png

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 weakReference;

public myhandler(MainActivity mainActivity){

weakReference=new WeakReference(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 相关知识,希望对大家有所帮助!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值