android应用中自动化埋点的实现,Android 自动化埋点方案
一、事件实现原理:
① View设置AccessibilityDelegate
②而当View 产生了click,long_click 等事件的时候.会在响应原有的Listener方法
③原有的Listener方法响应结束之后,然后在sendAccessibilityEvent方法中转发消息到AccessibilityDelegate
④在AccessibilityDelegate的sendAccessibilityEvent处理该事件
⑤不要调用call开头的方法如callOnClick,因为不能发送事件到sendAccessibilityEvent
如下方法可以使用
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
notifyEnterOrExitForAutoFillIfNeeded(true);
return result;
}
⑥、sendAccessibilityEvent生成事件的key和value
public void sendAccessibilityEvent(View host, int eventType) {
host.sendAccessibilityEventInternal(eventType);
}
二、Android组件生命周期埋点
①Activity生命周期
我们可以通过Application.ActivityLifecycleCallbacks来实现监听Activity的活动
②Service & BroadcastReciever生命周期
目前只能通过手动方式,至于实现方式可以修改如下代码
public class ActivityStatusManager implements Application.ActivityLifecycleCallbacks{
public final Integer STATUS_CREATED = 0x0001;
public final Integer STATUS_RESUMED = 0x0002;
public final Integer STATUS_PAUSED = 0x0003;
public final Integer STATUS_STARTED = 0x0004;
public final Integer STATUS_STOPED = 0x0005;
public final Integer STATUS_DESTROYED = -1;
private Map activityStack;
public void registerActivityLifecycleCallbacks(Application application) {
application.registerActivityLifecycleCallbacks(this);
}
public void unregisterActivityLifecycleCallbacks(Application application){
application.unregisterActivityLifecycleCallbacks(this);
}
private static class Holder{
public final static ActivityStatusManager instance = new ActivityStatusManager();
}
public static ActivityStatusManager shareInstance(){
return Holder.instance;
}
private ActivityStatusManager(){
activityStack = new ArrayMap();
}
public Integer getActivityStatus(Activity activity) {
final Integer status = activityStack.get(activity);
if(status==null){
return STATUS_DESTROYED;
}
return status;
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if(activity!=null){
activityStack.put(activity,STATUS_CREATED);
}
}
@Override
public void onActivityStarted(Activity activity) {
if(activity!=null){
activityStack.put(activity,STATUS_STARTED);
}
}
@Override
public void onActivityResumed(Activity activity) {
if(activity!=null){
activityStack.put(activity,STATUS_RESUMED);
}
}
@Override
public void onActivityPaused(Activity activity) {
if(activity!=null){
activityStack.put(activity,STATUS_PAUSED);
}
}
@Override
public void onActivityStopped(Activity activity) {
if(activity!=null){
activityStack.put(activity,STATUS_STOPED);
}
synchronized (Holder.instance){
int counter = 0;
for (Map.Entry entry : activityStack.entrySet()){
if(entry.getValue()==STATUS_STOPED){
counter++;
}
}
if(counter>0 && activityStack.size()==counter){
BaseApplication.setInForeground(false);
}else{
BaseApplication.setInForeground(true);
}
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
Application application = activity.getApplication();
activityStack.remove(activity);
clearInvalidActivity();
if(activityStack.isEmpty() && application!=null){
unregisterActivityLifecycleCallbacks(application);
}
}
public void clearInvalidActivity(){
Iterator> iterator = activityStack.entrySet().iterator();
do{
if(!iterator.hasNext()) return;
Map.Entry entry = iterator.next();
if(entry!=null && activityIsDestroyed(entry.getKey()) ){
iterator.remove();
}
}while(iterator.hasNext());
}
public void finishAll(){
if(activityStack.isEmpty()) return;
Activity activity = null;
Iterator> iterator = activityStack.entrySet().iterator();
do{
if(!iterator.hasNext()) return;
Map.Entry entry = iterator.next();
if(entry!=null ){
activity = entry.getKey();
if(activity!=null && !activityIsDestroyed(activity))
{
activity.finish();
}
iterator.remove();
}
}while(iterator.hasNext());
}
/**
* 程序是否在前台运行
*
* @return
*/
public boolean isForegroundProcess(Context context) {
// Returns a list of application processes that are running on the
// device
ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
String packageName = context.getApplicationContext().getPackageName();
List appProcesses = activityManager
.getRunningAppProcesses();
if (appProcesses == null)
return false;
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
private boolean activityIsDestroyed(Activity thatActivity){
if(thatActivity==null) return true;
if(Build.VERSION.SDK_INT>=17){
return thatActivity.isDestroyed() || thatActivity.isFinishing();
}else{
return thatActivity.isFinishing();
}
}
}
三、配置环境埋点
在Application中注册 ComponentCallbacks2
android应用中自动化埋点的实现,Android 自动化埋点方案相关推荐
- 如何在android模拟器中模拟sd卡,如何在Android模拟器中模拟SD卡
如何在Android模拟器中模拟SD卡 简介 Android允许开发者创建一个SD卡镜像并在启动模拟器加载它, 用于模拟物理设备中的SD卡. 下面将介绍: 1. 如何创建一个SD卡镜像? 2. 如何拷 ...
- Android Studio中使用Git——结合GitLab,Android热修复原理
在GitLab网站点击导航条上的 "+" 即可进入创建项目的页面,然后根据提示填写相应信息,如下图: Project path:项目路径 Project name:项目名称 Pro ...
- android开发中,手把手教你root Android系统
手把手教你root Android系统 因为从事的是智能家居相关行业,用的系统也是android系统,在某些场景下可能需要拿到系统的root权限.下面就手把手教大家去拿到app的root权限和adb的 ...
- Android开发中遇到的问题(二)——新建android工程的时候eclipse没有生成MainActivity和layout布局...
2019独角兽企业重金招聘Python工程师标准>>> 一.新建android工程的时候eclipse没有生成MainActivity和layout布局 最近由于工作上的原因,开始学 ...
- Android项目中遇到的坑之(Android圆角圆形图 二)
接着上一篇的问题来研究研究: **问题来了:效果是有了,但有发现么?我设置的scaleType只有fitxy 是有效果的,其他的都没有效果了.设置为其他的scaleType都变成matrix那种效果了 ...
- 解决android sdk中找不到tools目录Android sdkmanager tool not found (D:\Android\SDK\tools\bin\sdkmanager).
安装flutter时,使用flutter doctor报错: Android license status unknown. Try re-installing or updating your An ...
- android studio 陀螺仪,Android Studio中陀螺仪的例子吗?(Android Studio Gyroscope e
我试图建立它确实当设备被倾斜到一定程度所需影响的应用程序. 我已经采取了看,并成功启用,加速计,但是这并没有给我想要的影响. 就像我说的,我希望设备做什么,我希望它,只有当该设备已取得了一定的程度,说 ...
- 了解Android Studio中的Gradle
Gradle是啥? gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具. 所谓的构建过程就是:编译,测试,依赖管理,打包,部署.以前我们开发是手动导入jar包 ...
- 【转】如何单独编译Android源代码中的模块--不错
原文网址:http://blog.csdn.net//article/details/6566662/ 第一次下载好Android源代码工程后,我们通常是在Android源代码工程目录下执行make命 ...
- 【Android Protobuf 序列化】Protobuf 使用 ( protobuf-gradle-plugin 插件简介 | Android Studio 中配置插件 | AS 中编译源文件 )
文章目录 一.protobuf-gradle-plugin 插件简介 二.Android Studio 中配置 protobuf-gradle-plugin 插件 三.Android Studio 中 ...
最新文章
- Html emed 和 object
- 工业大数据的真正意义和价值
- 如何对比_潭酒红潭酱酒对比红花郎怎么样口感如何
- Newlife.Net QA
- 牛客题霸 [矩阵查找] C++题解/答案
- drools6.5_Drools 6.5.0.Final可用
- mysql 横向分表合并_MySQL横向扩展-分库分表解决方案总结
- android下挂串口中断,请大神看看为啥串口中断无法打断定时器中断
- easyUI中datagrid中getSelected和getSelections的用法
- 关于Centos Linux系统安装Python的问题
- 我们应当怎样做需求分析
- 缺少计算机所需的介质程序,UEFI安装Win8提示缺少所需的介质驱动程序怎么办?...
- TI的C28x系列芯片的存储结构(1)——总括
- 实验实例 —逻辑门设计
- 955.WLB 红包封面来啦!送给希望不加班的你~
- python自动售货机_Python:自动售货机
- 提升资源利用率与保障服务质量,鱼与熊掌不可兼得?
- 音创服务器怎样装xp系统,云骑士怎么装xp系统
- UDK 中的委托使用
- 经典算法——鸡尾酒排序(冒泡算法改良)