《疯狂Android讲义》第2版 第3.5.2节关于Handler的代码

类似定时切换商品效果:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_vertical"
    tools:context=".HandlerTest">

    <ImageView
        android:id="@+id/show"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#ff0000"
        />

</LinearLayout>

HandlerTest.java

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

import androidx.annotation.NonNull;

import java.util.Timer;
import java.util.TimerTask;

public class HandlerTest extends Activity {
    
    
    //定义周期性显示的图片的ID
    int[] imageIds = new int[]{
    
    
            R.drawable.java,
            R.drawable.ee,
            R.drawable.ajax,
            R.drawable.xml,
            R.drawable.classic
    };
    int currentImageId = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ImageView show = (ImageView) findViewById(R.id.show); //现在已经不需要强制转换了
        final Handler myHandler = new Handler() {
    
    
            @Override
            public void handleMessage(@NonNull Message msg) {
    
    
                if (msg.what == 0x1233) {
    
    
                    show.setImageResource(imageIds[currentImageId++]);
                    if (currentImageId >= 5) {
    
     //i++之后应该是5,书上写的4,有误。4会少显示一张图片。
                        currentImageId = 0;
                    }
                }
            }
        };

        //定义一个计时器,让该计时器周期性地执行指定任务
        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                //新启动的线程无法访问该Activity里的组件
                //所以需要通过Handler发送消息

                //这里我自己加的日志
                Log.d("HandlerTest", "线程名称:" + Thread.currentThread().getName());

                Message msg = new Message();
                msg.what = 0x1233;
                //发送消息
                myHandler.sendMessage(msg);
            }
        }, 0, 800);
    }
}

日志输出:

D/HandlerTest: 线程名称:Timer-0
D/HandlerTest: 线程名称:Timer-0
D/HandlerTest: 线程名称:Timer-0
D/HandlerTest: 线程名称:Timer-0

这个Timer-0线程是什么时候设置的?

        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
				...
            }
        }, 0, 800);

先看Timer的构造器:

public class Timer {
    
    
	//作为TimerThread的构造器入参
    private final TaskQueue queue = new TaskQueue();
    
    private final TimerThread thread = new TimerThread(queue);
    
    //serialNumber()方法在构造器中被调用
    //juc包里面的AtomicInteger,在多线程环境下也能进行原子操作
    private final static AtomicInteger nextSerialNumber = new AtomicInteger(0);
    private static int serialNumber() {
    
    
        return nextSerialNumber.getAndIncrement(); //返回值,然后把值加1
    }
    
    public Timer() {
    
     //Timer默认构造器
        this("Timer-" + serialNumber());
    }
    
    public Timer(String name) {
    
    
        thread.setName(name);
        thread.start();
    }
	
	...
}

给TimerThread类型的成员变量thread设置了name,并启动了。接着看看这个TimerThread。
TimerThread是Timer的同级类:

TimerThread继承自Thread,重写了run()方法。所以thread.start()就新建并启动了一个新线程。

class TimerThread extends Thread {
    
    

    boolean newTasksMayBeScheduled = true;

    private TaskQueue queue;

    TimerThread(TaskQueue queue) {
    
    
        this.queue = queue;
    }

    public void run() {
    
    
        try {
    
    
            mainLoop();
        } finally {
    
    
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
    
    
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }

    private void mainLoop() {
    
    
 
    	...
    }
}

猜你喜欢

转载自blog.csdn.net/zhangjin1120/article/details/131581907
今日推荐