android开发之app在线时长统计sdk开发

引言:

不少app的在线时长统计都是经过在activity的生命周期中埋点来完成的。我这里既然是封装成sdk,固然就不能这样来了。封装sdk的规则,我想你们都清楚,入参尽可能少,回调尽可能全,权限尽可能不要有。css

需求分析:

做为sdk,最好是在Application中初始化,入参,固然是applicationcontext为好,为啥?生命周期长呀。我这sdk做为观察app的在线时长的,固然不能随便就被回收了。而后是权限问题,低调,才会有人用。否则,用户被你一堆权限吓跑了。html

既然不能再每一个activity中埋点监听状态,那只好经过ApplicationContext找方法了。看看有没有可以监听全局的方法。一查api,还真有。那就开始造轮子。java

实践:

给个API所在地址:http://www.android-doc.com/reference/android/app/Application.htmlandroid

找找方法呗:
api

看到没,该方法很直接呀:activity生命周期回调。有了这个,大事可期!!!markdown

在点进去看看详情,确认一下:app

My god ,I love it !  简直是饿了送鸡腿,困了送枕头呀。ide

1.分析生命周期的场景

        1.activity被后台后强杀,结束,上报时长日志。this

        2.activity一层层的退出干净后,结束,上报时长日志。.net

2.撸代码

根据这两个场景,立马就开动了,使用一个map来记录activity的启动和结束,再用几个flag标记切换生命周期。可是,一通下来,发现,没这么简单呀。要考虑的东西真多。

首先,要对启动模式进行考虑。standard模式,A-B-A,生命周期,这个你们应该很熟。可是singletask就在监听中有了变化。A-B-A过程当中,A的onActivityStarted(Activity activity)方法中,activity并非你们期待的b的实例,而是a的实例。固然还有不少其余问题。不一一赘述。代码是最好的老师。

核心代码:

package com.ailin.shoneworn.OnLineStatics;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by admin on 2018/3/2.
 * @author  chenxiangxiang
 * shoneworn@163.com
 * 转载注明出处:http://www.cnblogs.com/shoneworn
 */

 class OnLineStatisticsClass {
    private String TAG = "OnlineStatics";

    private boolean isAppAlive = true;  //judge is app alive;
    private boolean isSwitchActivity = false;  // judge is switch activity from top to other in the stack of activity
    private boolean isAppExit = false;  //some times app have cleard the stack of activity but app is not exit . this boolean can help to static realive;

    private String topActivity ;
    private Map<String ,String> map = new HashMap<>();
    private long timeStart =0;   //start tag timestemp

    private OnLineImpl impl; //set a callback

    public void init(final Context context){
        Application application  = (Application)context.getApplicationContext();
        timeStart = System.currentTimeMillis()/1000;

        application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
                topActivity = activity.getClass().getSimpleName();
                map.put(topActivity,topActivity);
                isAppAlive = true;
                isSwitchActivity = false;
            }

            @Override
            public void onActivityStarted(Activity activity) {
            }

            @Override
            public void onActivityResumed(Activity activity) {
                //do you know why this logic is used here? because of the launch mode ,when activity start with SingleTask mode ,the onActivityStarted callback a top activity .
                if(!activity.getClass().getSimpleName().equals(topActivity)){
                    isSwitchActivity = true;
                }else{
                    isSwitchActivity = false;
                }
                topActivity=activity.getClass().getSimpleName();

               ..........................
            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                if(activity.getClass().getSimpleName().equals(topActivity) ){
                    if(!isSwitchActivity||map.size()==1){
                     ...................
                    }
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                map.remove(activity.getClass().getSimpleName());
                if(map.size()==0&&isAppAlive){
                    long timeEnd = System.currentTimeMillis()/1000;
                    if(impl!=null){
                        long timegap = timeEnd-timeStart;
                        String onlineTime = String.valueOf(timegap);
                        impl.onReportDuration(onlineTime);
                        timeStart = System.currentTimeMillis()/1000;
                    }
                    isAppAlive = false;
                }
                if(map.size() ==0){
                    isAppExit = true;
                }
            }
        });
    }


    public void setOnLineImpl(OnLineImpl impl){
        this.impl = impl;
    }

}

demo 下载地址:

https://download.csdn.net/download/shoneworn/10405179

相关文章
相关标签/搜索