性能优化之-使用HandlerThread

使用 HandlerThread 将loop转到子线程中处理分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅.
HandlerThread 其实也就是继承了Thread,并在run()方法内部执行Looper.prepare()和Looper.loop(), 
既然Looper 是在子进程创建的,所以消息的处理也就是在子进程处理的.

我们如果创建 Handler 时使用HandlerThread 的Looper,那创建的Handler 对象处理消息时也就是运作在和 HandlerThread 一样的子进程了.

public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

HandlerThread 有2个构造函数.

public HandlerThread(String name) {
    super(name);
    mPriority = Process.THREAD_PRIORITY_DEFAULT;
}

/**
 * Constructs a HandlerThread.
 * @param name
 * @param priority The priority to run the thread at. The value supplied must be from 
 * {@link android.os.Process} and not from java.lang.Thread.
 */
public HandlerThread(String name, int priority) {
    super(name);
    mPriority = priority;
}

第一个构造函数默认是使用Process.THREAD_PRIORITY_DEFAULT ,这个的优先级比较高,容易导致和UI 进程抢cpu,一般使用THREAD_PRIORITY_BACKGROUND.

int THREAD_PRIORITY_AUDIO //标准音乐播放使用的线程优先级
int THREAD_PRIORITY_BACKGROUND //标准后台程序
int THREAD_PRIORITY_DEFAULT // 默认应用的优先级
int THREAD_PRIORITY_DISPLAY //标准显示系统优先级,主要是改善UI的刷新
int THREAD_PRIORITY_FOREGROUND //标准前台线程优先级
int THREAD_PRIORITY_LESS_FAVORABLE //低于favorable
int THREAD_PRIORITY_LOWEST //有效的线程最低的优先级
int THREAD_PRIORITY_MORE_FAVORABLE //高于favorable
int THREAD_PRIORITY_URGENT_AUDIO //标准较重要音频播放优先级
int THREAD_PRIORITY_URGENT_DISPLAY //标准较重要显示优先级,对于输入事件同样适用。

实例:如何让BroadcastReceiver 的onReceive 运行在子进程而不是main 进程

这里记录一种简单的方法,就是使用Context的下面的方法

public abstract Intent registerReceiver(BroadcastReceiver receiver,
          IntentFilter filter, @Nullable String broadcastPermission,
          @Nullable Handler scheduler);

一般是注册广播接收器是这样写的:

context.registerReceiver(mBroadcastReceiver, filter);

但是这里需要使用上面带4个参数的registerReceiver方法.
其中String broadcastPermission 是可以null 的,关键在参数 Handler scheduler 上面.
在Handler scheduler 不为null 的时候,BroadcastReceiver 的 onReceive 就是运行在参数 Handler scheduler 所在的进程.
比如我们在一个activity 里面添加类似下面的代码:

HandlerThread handlerThread = new HandlerThread("HandlerThread_Broadcast");
handlerThread.start();
Handler broadcastHandler = new Handler(handlerThread.getLooper()) {
    public void handleMessage(Message msg) {
    //这里是可以做耗时操作的
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                
            }
        });
    }
};

private final Handler mHandler = new Handler() {}

IntentFilter bootCompleteFilter = new IntentFilter();
bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
context.registerReceiver(mBroadcastReceiver, bootCompleteFilter,null,broadcastHandler);

比如上面的例子,mBroadcastReceiver 的 onReceive() 和 broadcastHandler handleMessage 是运行在HandlerThread_Broadcast 这个子进程的,但是 mHandler 还是在主进程里面.

类似用法还有ContentObserver的带参数的构造函数

public ContentObserver(Handler handler) {
    mHandler = handler;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值