实现安卓一段时间不操作执行某段代码类似于屏保

前言

有些时候我们需要这样一个需求,比如屏保程序当规定时间不做任何操作就显示一张图片,又或者是安卓TV的菜单程序当用户在规定时间不操作的时候菜单自动关闭,还有很多其他的例子。

有两种实现方式一种是创建一个线程来计时另一种是使用Handler,而我会教大家使用Handler来实现,两种方式都差不多。都是实现计时,如果中途用户有操作就重新计时,等到时间到就执行某段程序。

下面先贴一份整体代码,然后我再讲解里面一些方法的用途

====源码下载====

整体代码

MainActivity.java

package com.my.screensaverdemo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class MainActivity extends Activity implements Screensaver.OnTimeOutListener {

    private Screensaver mScreensaver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScreensaver = new Screensaver(5000); //定时5秒
        mScreensaver.setOnTimeOutListener(this); //监听
        mScreensaver.start(); //开始计时
    }

    /**
     * 当触摸就会执行此方法
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        mScreensaver.resetTime(); //重置时间
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 当使用键盘就会执行此方法
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        mScreensaver.resetTime(); //重置时间
        return super.dispatchKeyEvent(event);
    }

    /**
     * 时间到就会执行此方法
     */
    @Override
    public void onTimeOut(Screensaver screensaver) {
        Log.d("MainActivity", "时间到了");
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mScreensaver.stop(); //停止计时
    }
}

Screensaver.java

package com.my.screensaverdemo;

import android.os.Handler;
import android.os.Message;

/**
 * 计时程序
 */
public class Screensaver {

    private static final int MSG_TIMEOUT = 0x0;

    private static final int SECOND = 1000;
    private static final int MINUTE = SECOND * 60;
    private static final int DEFAULT_TIMEOUT = MINUTE * 3; //默认为3分钟

    private OnTimeOutListener mOnTimeOutListener;
    private int mScreensaverTiemout = DEFAULT_TIMEOUT;//默认为3分钟

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what == MSG_TIMEOUT){

                //调用回调通知接收者
                if(mOnTimeOutListener != null){
                    mOnTimeOutListener.onTimeOut(Screensaver.this);
                }

                start(); //重新开始计时
            }
        }
    };


    public Screensaver(int screensaverTiemout) {
        mScreensaverTiemout = screensaverTiemout;
    }

    public Screensaver() {
    }


    /**
     * 开始计时
     */
    public void start() {
        Message message = mHandler.obtainMessage(MSG_TIMEOUT); //包装消息
        mHandler.sendMessageDelayed(message, mScreensaverTiemout); //延时发送消息
    }

    /**
     * 停止计时
     */
    public void stop() {
        mHandler.removeMessages(MSG_TIMEOUT); //移除消息
    }

    /**
     * 重置时间
     */
    public void resetTime() {
        stop();
        start();
    }

    public void setScreensaverTiemout(int mScreensaverTiemout) {
        this.mScreensaverTiemout = mScreensaverTiemout;
    }

    public int getScreensaverTiemout() {
        return mScreensaverTiemout;
    }

    public void setOnTimeOutListener(OnTimeOutListener onTimeOutListener) {
        this.mOnTimeOutListener = onTimeOutListener;
    }

    /**
     * 屏幕保护时间到监听
     */
    public interface OnTimeOutListener {
        void onTimeOut(Screensaver screensaver);
    }

}

实现原理

我们先来看一下MainActivity

mScreensaver = new Screensaver(5000); //定时5秒
mScreensaver.setOnTimeOutListener(this); //监听
mScreensaver.start(); //开始计时

第一行代码是创建一个计时器对象然后设置定时时间为5秒
第二行代码是设置监听,就是计时时间到的时候回调执行public void onTimeOut(Screensaver screensaver)方法
第三行就是开始计时。

    /**
     * 时间到就会执行此方法
     */
    @Override
    public void onTimeOut(Screensaver screensaver) {
        Log.d("MainActivity", "时间到了");
    }

这段代码就是实现的回调方法,计时时间到的时候会执行,我们可以在这个方法里面执行相应的操作。

    /**
     * 当触摸就会执行此方法
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        mScreensaver.resetTime(); //重置时间
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 当使用键盘就会执行此方法
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        mScreensaver.resetTime(); //重置时间
        return super.dispatchKeyEvent(event);
    }

这段代码是为了当用户执行键盘操作或者触摸操作就重新计时,如果读者不清楚dispatchTouchEvent和dispatchKeyEvent用来做什么的话可以查阅安卓的事件机制。

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mScreensaver.stop(); //停止计时
    }

最后是当应用退出的时候停止计时

下面我们来看一下Screensaver.java

    /**
     * 开始计时
     */
    public void start() {
        Message message = mHandler.obtainMessage(MSG_TIMEOUT); //包装消息
        mHandler.sendMessageDelayed(message, mScreensaverTiemout); //延时mScreensaverTiemout毫秒发送消息
    }

注释已经解释的很清楚,包装消息然后让它延时发送,当然mHandler是可以中途停止发送消息的。mHandler只是发送一次消息,为了能循环发送消息,所以后面接收消息的程序会再次执行这个方法。

    /**
     * 停止计时
     */
    public void stop() {
        mHandler.removeMessages(MSG_TIMEOUT); //移除消息
    }

这个方法就是用于停止发送消息

    /**
     * 重置时间
     */
    public void resetTime() {
        stop();
        start();
    }

重置时间就是先让mHandler停止延时发送消息,然后再次启动重新计时。

private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what == MSG_TIMEOUT){

                //调用回调通知接收者
                if(mOnTimeOutListener != null){
                    mOnTimeOutListener.onTimeOut(Screensaver.this);
                }

                start(); //重新开始计时
            }
        }
    };

这里使用了匿名内部类,是接收消息端,当接收到消息就会执行此方法,里面是先判断是否是MSG_TIMEOUT消息,然后执行回调方法通知实现了接口的MainActivity(对应的是onTimeOut方法),为了能循环计时,后面就加了一段start()。

public void setOnTimeOutListener(OnTimeOutListener onTimeOutListener) {
        this.mOnTimeOutListener = onTimeOutListener;
    }

    /**
     * 屏幕保护时间到监听
     */
    public interface OnTimeOutListener {
        void onTimeOut(Screensaver screensaver);
    }

这个就是回调接口了,当计时时间到就会通知实现了接口的对象,MainActivity已经实现了这个方法

mScreensaver.setOnTimeOutListener(this); //监听
    /**
     * 时间到就会执行此方法
     */
    @Override
    public void onTimeOut(Screensaver screensaver) {
        Log.d("MainActivity", "时间到了");
    }

原理就是这样子并没有太多的难点,不过有个问题没有解决,就是鼠标移动操作不能重置时间,当然如果是做手机应用可以完全忽略这点,作者是做投影仪的,有些时候需要使用鼠标,所以对这个比较关心。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值