AOP的简单应用
来源:互联网 发布:淘宝上的内存条能买吗 编辑:程序博客网 时间:2024/06/11 05:24
需求场景:无埋点实现监控到应用中所有的Button和Edittext。要求获取Button点击时压力和输入框每次输入字符时陀螺仪的值。
一开始思路是想办法获取要监控的控件对象,于是用到了registerActivityLifecycleCallbacks,代码如下:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } }); }}
这样可以获取到Activity对象,然后遍历Activity对象中所有的控件,遍历方法:
先获取view树:
View rootView = ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
然后调用:
private void traversalView(View view) { if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { View child = viewGroup.getChildAt(i); traversalView(child); } } else if (view instanceof EditText) { //当是edittext时加入自己的操作 onFindEditText((EditText) view); } else if (view instanceof Button) { //当是button时加入自己的操作 onFindButton((Button) view); } } private void onFindButton(final Button view) { view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.i("AA", view.getText().toString() + ":jar:down:" + event.getPressure() + ":" + event.getPressure(0)); break; case MotionEvent.ACTION_MOVE: Log.i("AA", "jar:move:" + ":jar:down:" + event.getPressure() + ":" + event.getPressure(0)); break; case MotionEvent.ACTION_UP: Log.i("AA", "jar:up:" + ":jar:down:" + event.getPressure() + ":" + event.getPressure(0)); break; } return false; } }); } private void onFindEditText(EditText view) { EditText et = view; TextWatcher watcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable editable) { Toast.makeText(application, "陀螺仪:" + "\nX:" + SensorUtils2.getInstence().X + "\nY:" + SensorUtils2.getInstence().Y + "\nZ:" + SensorUtils2.getInstence().Z + "\n传感加速器:" + "\nX:" + SensorUtils.getInstence().X + "\nY:" + SensorUtils.getInstence().Y + "\nZ:" + SensorUtils.getInstence().Z, Toast.LENGTH_LONG).show(); } }; et.addTextChangedListener(watcher); mEditTextMap.put(et, watcher); }
这样就实现了给遍历到的控件添加的监听,但是这样却不能拿到popupwindow和fragment里的控件。
于是转换思路,用到了面向切面编程的思想(AOP),其中一种就是AspectJ 参考http://blog.csdn.net/eclipsexys/article/details/54425414
完整代码:
package com.example.nieyuqi959.mylibrary;import android.text.Editable;import android.text.TextWatcher;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.EditText;import com.example.nieyuqi959.mylibrary.bean.Press;import com.example.nieyuqi959.mylibrary.bean.SensorValue;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;@Aspectpublic class AspectTest { private static final String TAG = "AA"; private String editable; @AfterReturning(value = "call(* android.view.View.findViewById(..))", returning = "returnvalue") public void onFindViewMethodAfter(Object returnvalue, JoinPoint joinPoint) throws Throwable { //次方法可以劫持到findviewbyid方法以及用butternife注解获取控件对象的方法 if (returnvalue instanceof Button) { ((Button) returnvalue).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); } else if (returnvalue instanceof EditText) { ((EditText) returnvalue).addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { } }); } Log.e("AA", "find控件" + (returnvalue instanceof Button) + (returnvalue instanceof EditText)); } @AfterReturning(value = "call(* android.support.v7.app.AppCompatActivity.findViewById(..))", returning = "returnvalue") public void onActivityFindViewMethodAfter(Object returnvalue, JoinPoint joinPoint) throws Throwable { //次方法是劫持Activity中findviewbyid方法 if (returnvalue instanceof Button) { ((Button) returnvalue).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); } else if (returnvalue instanceof EditText) { ((EditText) returnvalue).addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { } }); } Log.e("AA", "find控件" + (returnvalue instanceof Button) + (returnvalue instanceof EditText)); } @Before("execution(* android.text.TextWatcher.beforeTextChanged(..))") public void onBeforeTextChangedMethodBefore(JoinPoint joinPoint) throws Throwable { editable = ""; } @Before("execution(* android.view.View.OnTouchListener.onTouch(..))") public void onOntouchMethodBefore(JoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); MotionEvent motionEvent = (MotionEvent) args[1]; String eventTitle = null; switch (motionEvent.getAction()) { case 0: eventTitle = "down:"; break; case 2: eventTitle = "move:"; break; case 1: eventTitle = "up:"; break; } Button button = (Button) joinPoint.getArgs()[0];// WriteReadFile.getInstance().writeTxtToFile(eventTitle.equals("down") ? button.getText().toString() + "按钮压力值:" : "" + "\r\n" + eventTitle + ":" + motionEvent.getPressure(), null,"press.txt");// WriteReadFile.getInstance().save(eventTitle.equals("down") ? button.getText().toString() + "按钮传感加速器值:" : "" + "\r\n" + eventTitle + ":" + "\r\n" + "X:" + SensorAccelerometer.getInstence().X +// "\r\n" + "Y:" + SensorAccelerometer.getInstence().Y + "\r\n" + "Z:" + SensorAccelerometer.getInstence().Z, "accelerometer.txt");// WriteReadFile.getInstance().save(eventTitle.equals("down") ? button.getText().toString() + "按钮陀螺仪值:" : "" + "\r\nX:" + SensorGyroscope.getInstence().X+"\r\nY:"+SensorGyroscope.getInstence().Y+// "\r\nZ:"+SensorGyroscope.getInstence().Z, "gyroscope.txt"); ListValue.listPress.add(new Press(eventTitle, String.valueOf(motionEvent.getPressure()), button.getText().toString())); ListValue.listAccelerometer.add(new SensorValue(eventTitle, String.valueOf(SensorAccelerometer.getInstence().X), String.valueOf(SensorAccelerometer.getInstence().Y), String.valueOf(SensorAccelerometer.getInstence().Z), button.getText().toString())); ListValue.listGyroscope.add(new SensorValue(eventTitle, String.valueOf(SensorGyroscope.getInstence().X), String.valueOf(SensorGyroscope.getInstence().Y), String.valueOf(SensorGyroscope.getInstence().Z), button.getText().toString())); Log.e("AA", eventTitle + ":" + motionEvent.getPressure()); } @Before("execution(* android.text.TextWatcher.afterTextChanged(..))") public void onTextAfterChangedMethodBefore(JoinPoint joinPoint) throws Throwable { String s = joinPoint.getArgs()[0].toString(); if (!s.equals(editable)) { editable = s;// SensorAccelerometer.getInstence().registAccelerometer(); ListValue.listAccelerometer.add(new SensorValue(s, String.valueOf(SensorAccelerometer.getInstence().X), String.valueOf(SensorAccelerometer.getInstence().Y), String.valueOf(SensorAccelerometer.getInstence().Z), "输入框")); ListValue.listGyroscope.add(new SensorValue(s, String.valueOf(SensorGyroscope.getInstence().X), String.valueOf(SensorGyroscope.getInstence().Y), String.valueOf(SensorGyroscope.getInstence().Z), "输入框")); Log.e("AA", "获取陀螺仪:" + "\nX:" + SensorGyroscope.getInstence().X + "\nY:" + SensorGyroscope.getInstence().Y + "\nZ:" + SensorGyroscope.getInstence().Z); Log.e("AA", "传感加速器:" + "\nX:" + SensorAccelerometer.getInstence().X + "\nY:" + SensorAccelerometer.getInstence().Y + "\nZ:" + SensorAccelerometer.getInstence().Z); } }}
这样就是不需要动原来的项目就能实现需求。
阅读全文
0 0
- AOP的简单应用
- AOP的简单应用
- spring aop 的简单应用
- spring的aop切面的简单应用
- spring框架简单应用--aop
- 一个关于AOP简单应用的好博客地址
- 武林秘籍之Spring AOP 切面编程的简单应用
- spring中面向切面编程AOP的简单应用
- AOP技术应用和研究--AOP简单应用
- Spring AOP的应用
- Spring Aop的应用
- Spring AOP 的应用
- Spring的AOP应用
- AOP的实际应用
- AOP的应用
- AOP的简单实现
- AOP的简单示例
- AOP的简单认识
- mybaits xml 一对多 多端的关联一端 association 的用法。
- Http协议基础之HTTP通用首部字段
- 一款iOS 端 抓包组件
- 欢迎使用CSDN-markdown编辑器
- Android.mk的一些FAQ
- AOP的简单应用
- 程序员——高考的第二春
- FreeMarker
- 关于Android6.0 权限 文件读写
- 第十六周:( Sicily1321) Robot(c++)
- R-CNN,Fast R-CNN,Faster R-CNN
- git实现代码提交自动部署到相应的web服务器
- Java实现-不同的路径2
- 前端与后端的关系