Android -- Demo(二) 定时任务的四种实现方法:Timer、Thread、Handler & Alarm

Android – Demo(二) 定时任务的四种实现方法:Timer、Thread、Handler & Alarm

在这里插入图片描述

源代码:

public class Demo_TimingTask_Activity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "Demo_TimingTask_Activit";
    private final String ACTION_TASK = "com.nepalese.toollibs.alarm.task";
    private final String OUTCOME = "完成任务!";
    private final String FORMAT = "yyyy-MM-dd hh:mm:ss";

    private final int MSG_CODE_TASK = 0;
    private final int REQUEST_CODE_ALARM = 1;
    private final int MSG_CODE_ADD_LOG = 1;

    private Context context;
    private TextView tvTime, tvLog;
    private Button bTimer, bThread, bHandler, bAlarm;

    private int hour, min;
    private StringBuilder builder;
    private boolean isRegister = false;//记录是否开启receiver
    private boolean cancelTask = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo_timing_task);

        registerReceiver();//开启alarm监听
        init();
        setListener();
    }

    private void init() {
        context = getApplicationContext();
        builder = new StringBuilder();

        tvTime = findViewById(R.id.tvSelectTime);
        tvLog = findViewById(R.id.tvLog);

        bTimer = findViewById(R.id.bTimer);
        bThread = findViewById(R.id.bThread);
        bHandler = findViewById(R.id.bHandler);
        bAlarm = findViewById(R.id.bAlarm);
    }

    private void setListener() {
        tvTime.setOnClickListener(this);
        bTimer.setOnClickListener(this);
        bThread.setOnClickListener(this);
        bHandler.setOnClickListener(this);
        bAlarm.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.tvSelectTime:
                pickTime();
                break;
            case R.id.bTimer:
                startTimer();
                //避免再次点击
                bTimer.setEnabled(false);
                break;
            case R.id.bThread:
                startThread();
                bThread.setEnabled(false);
                break;
            case R.id.bHandler:
                startHandler();
                bHandler.setEnabled(false);
                break;
            case R.id.bAlarm:
                startAlarm();
                bAlarm.setEnabled(false);
                break;
        }
    }

    //简单时间选择对话框,仅hour 和 minute;
    private void pickTime() {
        Calendar calendar = Calendar.getInstance();
        int h = calendar.get(Calendar.HOUR_OF_DAY);
        int m = calendar.get(Calendar.MINUTE);
        TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int i, int i1) {
                hour = i;
                min = i1;
                tvTime.setText(hour+" : " + min);
            }
        },h,m,true);
        timePickerDialog.show();
    }

    private void startTimer() {
        long diff = getTimeDiff(hour, min);
        if(diff<0){
            addLog("The chosen time has passed!");
            return;
        }

        addLog("Start Timer Task, diff: " + diff/1000 +"s");
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                addLog("Timer: " + OUTCOME + ", " + DateUtil.long2String(System.currentTimeMillis(), FORMAT));
            }
        };

        timer.schedule(timerTask, diff);//仅执行一次

        //取消任务
//        timer.cancel();
//        timer = null;
//        timerTask.cancel();
//        timerTask = null;
    }

    private void startThread() {
        final long diff = getTimeDiff(hour, min);
        if(diff<0){
            addLog("The chosen time has passed!");
            return;
        }

        addLog("Start Thread Task, diff: " + diff/1000 +"s");
        //新开子线程
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(diff);
                    if(!cancelTask){
                        addLog("Thread: " + OUTCOME + ", " + DateUtil.long2String(System.currentTimeMillis(), FORMAT));
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        //取消任务
//        cancelTask = true;
    }

    private void startHandler() {
        long diff = getTimeDiff(hour, min);
        if(diff<0){
            addLog("The chosen time has passed!");
            return;
        }

        addLog("Start Handler Task, diff: " + diff/1000 +"s");
        handler.sendEmptyMessageDelayed(MSG_CODE_TASK, diff);

        //取消任务
//        handler.removeMessages(MSG_CODE_TASK);
    }

    private void startAlarm() {
        long diff = getTimeDiff(hour, min);
        if(diff<0){
            addLog("The chosen time has passed!");
            return;
        }

        addLog("Start Alarm Task, diff: " + diff/1000 +"s");
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(ACTION_TASK);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE_ALARM,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        if(alarmManager!=null){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, diff, pendingIntent);
            }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, diff, pendingIntent);
            }else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, diff, pendingIntent);
            }
        }

        //取消alarm
//        alarmManager.cancel(PendingIntent.getBroadcast(context, REQUEST_CODE_ALARM,
//                new Intent(ACTION_TASK), PendingIntent.FLAG_UPDATE_CURRENT));
    }

    //计算目标时间与当前时差
    private long getTimeDiff(int hour, int min){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, hour);//24-hour clock
        calendar.set(Calendar.MINUTE, min);
        calendar.set(Calendar.SECOND, 0);

        long mm = calendar.getTimeInMillis();
        long now = System.currentTimeMillis();

        return mm - now;
    }

    //由于在子线程无法更新UI, 一致使用handler发送UI更新消息;
    private void addLog(String log){
        builder.append(log);
        builder.append("\n");

        Message message = Message.obtain();
        message.what = MSG_CODE_ADD_LOG;
        message.obj = builder.toString();
        handler.sendMessage(message);
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case MSG_CODE_TASK:
                    addLog("Handler: " + OUTCOME + ", " + DateUtil.long2String(System.currentTimeMillis(), FORMAT));
                    break;
                case MSG_CODE_ADD_LOG:
                    //log 更新
                    tvLog.setText((String)msg.obj);
                    break;
            }
        }
    };

    //==========================动态注册alarm监听==============================
    private void registerReceiver() {
        if (!isRegister) {
            isRegister = true;
            IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION_TASK);
            registerReceiver(alarmTask, filter);
            Log.i(TAG, "registerReceiver");
        }
    }

    //取消监听
    public void unRegisterReceiver() {
        if (isRegister) {
            isRegister = false;
            unregisterReceiver(alarmTask);
            Log.i(TAG, "unRegisterReceiver");
        }
    }

    private BroadcastReceiver alarmTask = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            addLog("onReceive: alarmTask");
            String action = intent.getAction();
            if (ACTION_TASK.equals(action)) {
                addLog("Alarm: " + OUTCOME + ", " + DateUtil.long2String(System.currentTimeMillis(), FORMAT));
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unRegisterReceiver();
    }
}

布局文件:

<?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"
    tools:context=".Activity.Demo.Demo_TimingTask_Activity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/padding_10"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Time: "
            android:textSize="@dimen/text_size_20"
            android:textColor="@color/colorBlack"/>

        <TextView
            android:id="@+id/tvSelectTime"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="click to pick time!"
            android:layout_marginLeft="@dimen/margin_5"
            android:textSize="@dimen/text_size_20"
            android:textColor="@color/colorRed"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/padding_10"
        android:layout_marginTop="@dimen/margin_10"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bTimer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Timer"
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"/>

        <Button
            android:id="@+id/bThread"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Thread"
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"/>

        <Button
            android:id="@+id/bHandler"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Handler"
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"/>

        <Button
            android:id="@+id/bAlarm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Alarm"
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"/>

    </LinearLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/margin_10"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tvLog"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="@dimen/padding_15"
            android:hint="log"
            android:background="@color/colorGery_Half"
            android:textSize="@dimen/text_size_20"
            android:textColor="@color/colorBlack"/>
    </ScrollView>
</LinearLayout>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值