android统计sdk技术分享,android开发之app在线时长统计sdk开发

引言:

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

需求分析:

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

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

实践:

找找方法呗:

492994c7300fe5a5af46041b0fe84f70.png

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

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

0707616061b1d65f071214f4d7e4173a.png

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

1.分析生命周期的场景

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

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

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 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 下载地址:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值