import android.app.Activity; import android.app.Application; import android.content.Context; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; imp
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* 可以做日志埋点
* 异常监控
* 使用:
* 1.BaseActivity里重写该方法
*
* @Override public boolean dispatchTouchEvent(MotionEvent ev) {
* StepsHelper.getInstance().onDispatchTouchEvent(this, ev);
* return super.dispatchTouchEvent(ev);
* }
* 2.MyApplication#ibCreate里调用
* StepsHelper.registerActivityLifecycleCallbacks(context);
*/
public class StepsHelper {
/**
* 插桩开关
*/
private boolean isOff = false;
private static List<String> stepQueue = new ArrayList<>(); //储存用户操作步骤的队列
private static StringBuilder stepBuilder = new StringBuilder();
private float lastX;
private float lastY;
private static StepsHelper mStepsHelper = null;
private StepsHelper() {
}
public static StepsHelper getInstance() {
synchronized (StepsHelper.class) {
if (mStepsHelper == null) {
mStepsHelper = new StepsHelper();
}
}
return mStepsHelper;
}
public static void registerActivityLifecycleCallbacks(Application context) {
context.registerActivityLifecycleCallbacks(new ActivityLifecycle());
}
public void onCreate(Activity activity) {
enqueueStep(activity, "onCreate");
}
public void onResume(Activity activity) {
enqueueStep(activity, "onResume");
}
public void onPause(Activity activity) {
enqueueStep(activity, "onPause");
}
public void onDestroy(Activity activity) {
enqueueStep(activity, "onDestroy");
}
/**
* 状态进入步骤队列
*/
public void enqueueStep(Context context, String state) {
if (!isOff) {
return;
}
String time = DateUtil.formatCurrentDate(DateUtil.REGEX_DATE_TIME);
stepBuilder.append(time)
.append(" ")
.append(context.getClass().getName())
.append(" ")
.append(state);
String s = stepBuilder.toString();
stepQueue.add(s);
XLog.commonLog("插桩日志", s);
stepBuilder.delete(0, stepBuilder.length());
}
/**
* 视图进入步骤队列
*/
public void enqueueStep(Context context, View view) {
if (view == null || !isOff) {
return;
}
String time = DateUtil.formatCurrentDate(DateUtil.REGEX_DATE_TIME);
String path = view.getResources().getResourceName(view.getId());
String viewId = path.substring(path.indexOf("/") + 1);
stepBuilder.append(time)
.append(" ")
.append(context.getClass().getName())
.append(" Event:viewId:")
.append(viewId)
.append(" Type: ")
.append(view.getClass().getName());
String s = stepBuilder.toString();
stepQueue.add(s);
XLog.commonLog("插桩日志", s);
stepBuilder.delete(0, stepBuilder.length());
}
/**
* 触摸事件
*/
public void onDispatchTouchEvent(Activity activity, MotionEvent event) {
if (!isOff) {
return;
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
this.lastX = event.getRawX();
this.lastY = event.getRawY();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
float currentX = event.getRawX();
float currentY = event.getRawY();
if (lastX == currentX && lastY == currentY) {
// 判断是点击操作
View view = this.getView(activity.getWindow().getDecorView(), currentX, currentY);
// 把view事件记录到队列里边
enqueueStep(activity, view);
}
}
}
private View getView(View decorView, float currentX, float currentY) {
View targetView = null;
int[] pos = new int[2];
decorView.getLocationInWindow(pos);
if (determinePos(currentX, currentY, pos[0], pos[1], decorView.getWidth(), decorView.getHeight())) {
if (decorView instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) decorView).getChildCount(); ++i) {
View tempView = ((ViewGroup) decorView).getChildAt(i);
// 递归获取目标view
targetView = getView(tempView, currentX, currentY);
if (targetView != null) {
break;
}
}
} else {
targetView = decorView;
}
}
return targetView;
}
// 判断触控点在窗口范围内
private boolean determinePos(float var1, float var2, int var3, int var4, int var5, int var6) {
return var1 >= (float) var3 && var1 <= (float) (var3 + var5) && var2 >= (float) var4 && var2 <= (float) (var4 + var6);
}
public static String flushString() {
String s = stepQueue.toString();
stepQueue.clear();
return s;
}
private static class ActivityLifecycle implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
StepsHelper.getInstance().onCreate(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
StepsHelper.getInstance().onResume(activity);
}
@Override
public void onActivityPaused(Activity activity) {
StepsHelper.getInstance().onPause(activity);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
StepsHelper.getInstance().onDestroy(activity);
}
}
}