一、Handler的简单使用:
TestActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
private void init() {
handler.sendEmptyMessage(111);
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 111){
//通知到了,开始对应的业务
}
}
};
简单说就是Handler 匿名内部类作为一个监听器,提前写好,消息来了,验证是需要的消息,然后执行业务。
handler.sendEmptyMessage方法负责发送消息。
handleMessage方法负责监听消息。
二、Handler实现进度条:
activity_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progerss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="60"/>
</LinearLayout>
这里面的max="60"代表进度条的进度最多是60
TestActivity.java:
public class TestActivity extends Activity {
private ProgressBar progressBar;
private int jindu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
init();
}
private void init() {
progressBar = findViewById(R.id.progerss);
//启动进度条
handler.sendEmptyMessage(111);
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 111){
if (jindu<60){
progressBar.setProgress(jindu);
jindu++;
//每秒自动发通知,自己接收
handler.sendEmptyMessageDelayed(111,1000);
}
}
}
};
}
这里需要需要了解,第一次handler.sendEmptyMessage(111);是为了启动进度条,然后Handler 收到通知,setProgress设置进度,然后jindu变量加一,然后handler.sendEmptyMessageDelayed(111,1000);再以一秒为单位发新通知,然后再接收,循环,直到进度到60,进度条满。
三、Handler实现轮播:
activity_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
TestActivity.java:
public class TestActivity extends Activity {
private ViewFlipper flipper;
private Message message;
private int[] imgs = new int[]{R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
init();
}
private void init() {
flipper = findViewById(R.id.flipper);
for (int i = 0; i < imgs.length; i++) {
ImageView imageView = new ImageView(TestActivity.this);
imageView.setImageResource(imgs[i]);
flipper.addView(imageView);
}
message = Message.obtain();
message.what = 111;
handler.sendMessage(message);
//觉得轮播效果不行可以自己做个滑进滑出的动画,用setInAnimation设置给flipper
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 111){
flipper.showPrevious();
message = handler.obtainMessage(111);
handler.sendMessageDelayed(message,1000);
}
}
};
}
四个图片的资源文件自己看着弄。ViewFlipper 在这里面也是基本使用,不做详述。
flipper.showPrevious();就是显示下一个图片
message = handler.obtainMessage(111);就是取到消息,用这个可以不创建新的message ,直接从消息池取空的消息。
message = Message.obtain();也是同理。
handler.sendMessageDelayed(message,1000);作用是每秒发一次通知,因为Handler 每次收到通知会显示下一个图片,自然轮播效果就实现了。
四、子线程中使用Handler:
上面的我们都是用的主线程中的handler,如果我们在子线程中使用,就会报错,说不能用Looper.prepare()。
这里也就是涉及到了handler处理消息机制。
首先,我们new一个message,message应该给handler处理,但是呢,有时候很多消息,所以就会有一个消息栈,这个消息栈是一个先进先出的栈,这个会把所有的消息,先放进这个里面,然后由一个“循环工人”不断的轮询取出最先进的,发给handler。这个“循环工人”就是Looper。
正常主线程中,会默认帮我们创建一个,所以主线程中使用handler完全没问题,但是子线程就需要我们自己创建启动了。
具体代码:
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Looper.prepare();//创建新的Looper
super.handleMessage(msg);
if (msg.what == 111){
//通知到了,开始对应的业务
}
Looper.loop();//开启Looper
}
}
创建并启动looper就是上面加注释的两行代码,注意他们的位置。
还要注意Looper.loop();下面的代码不会执行,所以不要在下面再写业务逻辑了。