欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android的handler基本使用以及做一个简单进度条和轮播图以及子线程中用handler

程序员文章站 2022-03-30 10:16:34
一、Handler的简单使用:TestActivity.java: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } private void init() { handler.sendEmptyMessage(111); } Handler ha...

一、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();下面的代码不会执行,所以不要在下面再写业务逻辑了。

本文地址:https://blog.csdn.net/sadkhkuhkjasga/article/details/107214018