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

来源:互联网 发布:服装淘宝店从哪里进货 编辑:程序博客网 时间:2024/06/09 17:09

前言

有些时候我们需要这样一个需求,比如屏保程序当规定时间不做任何操作就显示一张图片,又或者是安卓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", "时间到了");    }

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

2 0
原创粉丝点击