美文网首页
Android应用前后台监听

Android应用前后台监听

作者: ModestStorm | 来源:发表于2022-09-15 12:31 被阅读0次

配置文件

public class MpaasConfigs {
    /*ActivityLifecycle*/
    public static final int ON_FORNTGROUND = 0;
    public static final int ON_BACKGROUND = 1;
    public static final int ON_CHANGE = 2;
    public static final int ON_ACTIVITY_CREATED = 3;
    public static final int ON_ACTIVITY_PAUSED = 4;
    public static final int ON_ACTIVITY_RESUMED = 5;
    public static final int ON_ACTIVITY_STARTED = 6;
    public static final int ON_ACTIVITY_STOPED = 7;
    public static final int ON_APP_FORNTGROUND = 8;
    public static final int ON_APP_BACKGROUND = 9;
    public static final long CHECK_DELAY = 600;
}

被观察者

 /* 说明:生命周期监控类 单例模式 观察者模式
 * java.util.Observable
 * Observable就是可以被观察的,程序中的被观察者类,需要继承这个类。
1.当onActivityResumed()被调用时表示app处于前台通知观察者
2.在onActivityStart调用时activityCount++
3.在onActivityStop调用时activityCount--并判断activityCount是否等于0,是的话说明app处于后台,通知观察者
因为被观察者是单例,为了防止保存activity信息出现内存泄漏情况,使用weakReference弱引用保存
 * ******************************
 */

public class ApplicationLifecycleObservable extends Observable implements Application.ActivityLifecycleCallbacks {

    //activity事件回调需要在ui线程中操作
    private Handler mMainHandler = null;
    private Activity mCurrentActivity = null;
    private int activityCount = 0;
    private boolean mIsPaused = false;
    private boolean mIsForeground = false;
    private String mCurActivityHash = null;
    private Runnable mCheckRunnable = null;

    private ApplicationLifecycleObservable() {
    }

    private static class ApplicationLifecycleObservableHolder {
        private static ApplicationLifecycleObservable INSTANCE = new ApplicationLifecycleObservable();
    }

    public static ApplicationLifecycleObservable getInstance() {
        return ApplicationLifecycleObservableHolder.INSTANCE;
    }

    public void initApplication(Application application){
        if(application != null){
            application.unregisterActivityLifecycleCallbacks(this);
            application.registerActivityLifecycleCallbacks(this);
        }

        mMainHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityCreated  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        this.mCurrentActivity = activity;
        notifyObservers(MpaasConfigs.ON_ACTIVITY_CREATED);
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityStarted  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        this.mCurrentActivity = activity;
        notifyObservers(MpaasConfigs.ON_ACTIVITY_STARTED);
        if(activityCount == 0){
            Log.d("ApplicationLifecycleObservable  -->  Lifecycle >>>>>>>>>>>>>>>>>>> APP  Foreground");
            notifyObservers(MpaasConfigs.ON_APP_FORNTGROUND);
        }
        activityCount++;
    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityResumed  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        this.mCurrentActivity = activity;
        notifyObservers(MpaasConfigs.ON_ACTIVITY_RESUMED);
        mIsPaused = false;
        boolean wasBackground = !mIsForeground;
        mIsForeground = true;
        String activityHash = getActivityHash(activity);
        if(!activityHash.equals(mCurActivityHash)){
            notifyObservers(MpaasConfigs.ON_CHANGE);
            mCurActivityHash = activityHash;
        }

        final WeakReference<Activity> mActivityWeakReference = new WeakReference<>(activity);

        //通知用户应用到达前台, 延迟600ms
        mMainHandler.postDelayed(mCheckRunnable = new Runnable() {
            @Override
            public void run() {
                //如果应用之前在后台状态则通知应用已经到达前台
                if(wasBackground){
                    Activity ac = mActivityWeakReference.get();
                    if(null == ac){
                        Log.d("ApplicationLifecycleObservable  -->  onFront activity is null!");
                        return;
                    }
                    notifyObservers(MpaasConfigs.ON_FORNTGROUND);
                }
            }
        },MpaasConfigs.CHECK_DELAY);
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityPaused  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        this.mCurrentActivity = activity;
        notifyObservers(MpaasConfigs.ON_ACTIVITY_PAUSED);
        mIsPaused = true;
        if(mCheckRunnable != null){
            mMainHandler.removeCallbacks(mCheckRunnable);
        }
        final WeakReference<Activity> mActivityWeakReference = new WeakReference<>(activity);
        mMainHandler.postDelayed(mCheckRunnable = new Runnable() {
            @Override
            public void run() {
                if(mIsForeground && mIsPaused){
                    mIsForeground = false;
                    Activity ac = mActivityWeakReference.get();
                    if(null == ac){
                        Log.d("ApplicationLifecycleObservable  -->  onBackground activity is null!");
                        return;
                    }
                    notifyObservers(MpaasConfigs.ON_BACKGROUND);
                }
            }
        },MpaasConfigs.CHECK_DELAY);
    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityStopped  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        this.mCurrentActivity = activity;
        notifyObservers(MpaasConfigs.ON_ACTIVITY_STOPED);
        activityCount--;
        if(activityCount == 0){
            Log.d("ApplicationLifecycleObservable  -->  >>>>>>>>>>>>>>>>>>> APP  Background ");
            notifyObservers(MpaasConfigs.ON_APP_BACKGROUND);
        }
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
        Log.d("ApplicationLifecycleObservable  -->  onActivityDestroyed  Lifecycle : " + System.currentTimeMillis() +"   activity name   "+activity.getLocalClassName());
        if(getActivityHash(activity).equals(mCurActivityHash)) {
            mCurActivityHash = null;
        }

        this.mCurrentActivity = null;
    }

    @Override
    public void notifyObservers(Object arg) {
        setChanged();
        super.notifyObservers(arg);
    }

    private String getActivityHash(Activity activity){
        return activity.getClass().getName() + activity.hashCode();
    }

    public Activity getmCurrentActivity() {
        return mCurrentActivity;
    }

观察者

/**
 * 说明:java.util.Observer
 * 这个是观察者,是接口。程序中的观察者类,需要实现这个接口中的update()方法。
 * 这个是观察者base类
 * ******************************
 */

public class BaseLifecycleObserver implements Observer {

    public void onActivityFrontground(Activity activity) {

    }

    public void onActivityBackground(Activity activity) {

    }

    public void onChange(Activity activity) {

    }

    void onActivityCreated(Activity activity) {

    }

    void onActivityStarted(Activity activity) {

    }

    void onActivityResumed(Activity activity) {

    }

    void onActivityPaused(Activity activity) {

    }

    void onActivityStopped(Activity activity) {

    }

    public void onAppForeground() {

    }

    public void onAppBackground() {

    }

    @Override
    public void update(Observable o, Object arg) {
        try {
            ApplicationLifecycleObservable observable = (ApplicationLifecycleObservable) o;
            int index = (int) arg;
            Activity activity = observable.getmCurrentActivity();
            switch (index) {
                case MpaasConfigs.ON_FORNTGROUND:
                    if(activity != null){
                        onActivityFrontground(activity);
                    }
                    break;
                case MpaasConfigs.ON_BACKGROUND:
                    if(activity != null){
                        onActivityBackground(activity);
                    }
                    break;
                case MpaasConfigs.ON_CHANGE:
                    if(activity != null){
                        onChange(activity);
                    }
                    break;
                case MpaasConfigs.ON_ACTIVITY_CREATED:
                    if(activity != null){
                        onActivityCreated(activity);
                    }
                    break;
                case MpaasConfigs.ON_ACTIVITY_PAUSED:
                    if(activity != null){
                        onActivityPaused(activity);
                    }
                    break;
                case MpaasConfigs.ON_ACTIVITY_RESUMED:
                    if(activity != null){
                        onActivityResumed(activity);
                    }
                    break;
                case MpaasConfigs.ON_ACTIVITY_STARTED:
                    if(activity != null){
                        onActivityStarted(activity);
                    }
                    break;
                case MpaasConfigs.ON_ACTIVITY_STOPED:
                    if(activity != null){
                        onActivityStopped(activity);
                    }
                    break;
                case MpaasConfigs.ON_APP_FORNTGROUND:
                    if(activity != null){
                        onAppForeground();
                    }
                    break;
                case MpaasConfigs.ON_APP_BACKGROUND:
                    if(activity != null){
                        onAppBackground();
                    }
                    break;
                default:
                    break;
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

AppForegroundMonitor

public class AppForegroundMonitor extends BaseLifecycleObserver {

    private static AppForegroundMonitor appForegroundMonitor;

    private AppForegroundMonitor() {}

    public static AppForegroundMonitor getInstance() {
        if (appForegroundMonitor == null) {
            synchronized (AppForegroundMonitor.class) {
                if (appForegroundMonitor == null) {
                    appForegroundMonitor = new AppForegroundMonitor();
                }
            }
        }

        return appForegroundMonitor;
    }

    private long appForegroundTime;

    @Override
    public void onAppForeground() {
        appForegroundTime =  SystemClock.elapsedRealtime();
    }

    @Override
    public void onAppBackground() {
        if (appForegroundTime == 0) return;
        //app在前台停留的时间
        long appForegroundStayTime = SystemClock.elapsedRealtime() - appForegroundTime;
        appForegroundTime = 0;
 
        if (appForegroundStayTime <= 0) return;
        //根据上传策略进行上报
    }
}

使用

// 初始化生命周期监听类
 ApplicationLifecycleObservable.init(app);

 // 应用前台时长统计 添加观察者
ApplicationLifecycleObservable.getInstance().addObserver(AppForegroundMonitor.getInstance());

相关文章

  • Android:监听应用前后台切换及思考

    Android:监听应用前后台切换 需求:监听应用前后台切换 分析:监听应用前后台切换实现方式有两种 1.起一个线...

  • Android 监听应用前/后台切换

    前言 这周接到一个需求,需要在应用从后台切换到前台时,展示我们的广告。展示页面其实可以复用以前的开屏广告页,唯一的...

  • Android应用前后台监听

    配置文件 被观察者 观察者 AppForegroundMonitor 使用

  • AccessibilityService使用入门

    AccessibilityService设计初衷在于帮助残障用户使用android设备和应用,在后台运行,可以监听...

  • Android中监听应用进入后台

    最近看到好几个银行类app,应用切出去之后会提示“XXX进入后台运行” API 14之后,Application可...

  • Android前后台切换监听

    简述 Android中部分业务会需要监听前后台切换 , 而一般前后台监听有两种方案 : 在Application中...

  • Android jetpack(Lifecycle篇)

    今天逛简书,看到有人问Android 怎么监听整个应用进入了后台,我看底下的评论有人说,做一个BaseActivi...

  • ContentObserver原理

    ContentObserver是android上监听内容变化的常用工具,既可以监听本应用的,也可以监听其他应用的内...

  • 史上最详细的微信抢红包详解

    一.技术背景 辅助功能设计初衷在于帮助残障用户使用android设备和应用,在后台运行,可以监听用户界面的一些状态...

  • Android_监听应用程序在后台

    如何监听程序在后台 有时候,我们为了实现某种需求,需要隔一段时间监听一下程序是否在后台,那么如何做呢? 分析需求 ...

网友评论

      本文标题:Android应用前后台监听

      本文链接:https://www.haomeiwen.com/subject/hmzkortx.html