⑴ Handler源码分析
Handler对于android开发者再熟悉不过了,也是面试题的常客了,所以了解Handler机制的源码就很有必要了,虽然Handler分析的文章已经有很多,但是自己总结一遍,印象才更深刻。
Handler机制,是Android中的一种消息传递机制,在开发中十分常用。由于Android从3.0开始不允许耗时操作在主线程中执行,必须在子线程中执行完后,将结果发送到主线程中更新UI。所以简单来讲Handler就是子线程和主线程通信的一种技术。
先是常规使用,Handler在主线程中创建,开启子线程处理耗时操作,再通过Handler发送消息到主线程,Handler的handleMessage()方法就会被回调,再更新UI。
以及也很常用的,post()和postDelayed()。
还有一种场景,就是子线程中创建Handler,让子线程成为轮训的线程,接收其他线程的消息,开发中并不多,但是特定场景会很有用,例如有一个一直执行的子线程,一直定时扫描着当前位置信息,到了指定范围,发送一个播放语音的消息的消息到主线程。
接下来就是Handler源码分析了:
一般我们获取Message会调用Handler的obtainMessage()方法,这个方法是获取一个复用的Message对象,内部采用享元模式复用Message对象,在Android中,View绘制,Activity生命周期,都是使用Handler发送Message实现,如果每次都new一个消息对象,肯定是十分消耗内存的,也容易产生GC垃圾回收导致卡顿。
我们平常在主线程使用Handler时,并没有调用过Looper.prepare()和Looper.loop()这2个方法,为什么创建Handler时不会抛出异常呢?
原因就是创建Handler时,调用Looper.myLooper()获取主线程绑定的Looper不为空,所以没有抛出异常。经过Looper类中查找发现,除了Looper.prepare()之外,还有一个prepareMainLooper()的方法。
prepareMainLooper()方法的注释,意思大概就是,创建主线程的Looper对象,该方法由Android框架在主线程自动调用,我们不应该主动调用该方法。
那么什么时候会调用prepareMainLooper()方法呢,AndroidStudio点击方法查找调用链,我们发现在ActivityThread中有调用。ActivityThread是Android程序的主线程,main方法则是启动的方法,我们看到先是调用了Looper.prepareMainLooper(),初始化主线程的Looper。再调用了Looper.loop()开启主线程轮训。
⑵ 如何定时刷新Android界面
Handler.sendEmptyMessageDelayed(0, 1000);来实现
sendEmptyMessageDelayed:延时多少毫秒,向Handler发送信息
具体代码和效果
每隔1秒刷新一次时间
⑶ android studio怎么编写计时器
类似iOS中的NSTimer 定时器功能,开关控制随机几秒钟执行指定功能;
平台:Android
开发环境:android Studio
代码实现:
一. 创建Handler对象和Runnable对象
[java] view plain print?
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (mPageOpen){
if (interstitialAd.isLoaded()){ //示例-谷歌插页广告
interstitialAd.show();
}else {
AdRequest adRequest = new AdRequest.Builder().build();
interstitialAd.loadAd(adRequest);
}
int random = (int)(Math.random() * 10 +20)*1000; //随机时间循环执行
handler.postDelayed(this, random);
}
}
};
二. 开关控制
[java] view plain print?
Switch mSwith = (Switch) findViewById(R.id.switchPage);
mSwith.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mPageOpen = true;
} else {
mPageOpen = false;
}
handler.postDelayed(runnable, 15000); //开关控制执行
}
});
三. 移除定时器
[java] view plain print?
handler.removeCallbacks(runnable);
⑷ 安卓定时器Handler如何关闭
{
publicTimeCounts(longmillisInFuture,longcountDownInterval){
super(millisInFuture,countDownInterval);//参数依次为总时长,和计时的时间间隔
}
@Override
publicvoidonFinish(){//计时完毕时触发
}
@Override
publicvoidonTick(longmillisUntilFinished){//计时过程显示
//倒计时数可以写在这儿
}
}
TimeCounts timeCounts = new TimeCounts(30000, 1000);//总时长30s,间隔1s
timeCounts.start();//倒计时开始
timeCounts.cancel();//取消倒计时
⑸ android设置定时器调用时设置时间
你的意思是,假设3个RadioButton,第一个设为10秒,第二个设为20秒,第三个设为30秒,然后一起倒计时到0吗?如果是这样的话,只需要在Handler的handleMessage中去减时间就行了。
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
xx.setText(Integer.parseInt(xx.getText()-1);
}
};