最近接触了Android开发中用到的比较火的一个框架——Xposed框架。那么什么是Xposed框架呢?
(文章参考了http://blog.youkuaiyun.com/zhangmiaoping23/article/details/52572447)
1、什么是Xposed框架?
百度百科上给出的定义是:Xposed是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,基于Xposed可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。
优点:Xposed是基于AOSP(android open source project)开发的,对源代码改动不大的ROM兼容性比较好,这也就使得某一功能可以借助Xposed移植到不同的ROM上。例如:现在你的手机上所拥有的功能你已经很喜欢了,但是又羡慕其他系统所独特拥有的功能,那么我们就可以通过Xpose框架将另一系统上的某些功能模块移植到我们自己的android系统上。如果想要恢复系统的原状的话,只需要在Xposed里取消对其他功能的勾选就可以了。
注意:Xposed的安装需要root权限。
2、Xposed框架如何配置在eclipse上,进行模块的开发?
首先准备好eclipse、XposedBridge.jar包、SDK、JDK。将XposedBridge.jar包放在新建项目的lib/libs下面,然后右键buildpath
3、Xposed框架的核心思想?
Xposed的核心思想是将Java层的普通的函数注册成本地的JNI(Java native interface)方法,以此来变相实现hook机制。
Java native interface:它提供了若干的API,实现了Java和其他语言的通信(主要是C/C++)
3.1 Android程序是在Dalvik虚拟机上运行的,那么Dalvik在执行Java层代码时,是如何识别JNI方法的?首先来看一下类的的加载过程:(类第一次被使用)——>(类的字节码被加载到内存)——>(字节码的入口维持着该类所有方法描述符的list) 这些描述符包含着:(方法代码存于何处)(有哪些参数)如果一个方法描述符内有native,这些描述符快将有一个指向该方法的实现的指针。
一个类执行之前会先被装载,之后需要字节码验证,检验完成之后,虚拟机会紧接着调用findClass()来查找并装载main的方法类,然后再调用类中的成员函数.CallStaticVoidMethod执行main方法,程序开始运行。
3.2那么我们如何将Java层的普通的方法注册成JNI方法呢?
3.3xposed框架在其中做了些什么呢?
4、微信运动
微信运动是想获取到我们走了多少步。Android机会有自带的计数传感器。当应用程序想要知道我们走了多少步的时候,需要去询问计数传感器;计数传感器得到请求
之后,会把步数返回给应用程序,这样的话,应用程序就可以通过页面向我们展示我们走的步数了。所以,如果我们想要在不知不觉的情况下,修改步数的话,我们就需要在计
数传感器向应用程序返回数据的时候,进行拦截,然后修改处理逻辑,再将数据返回。
因为是第一次真正的接触android,所以下面的代码是参考着http://blog.youkuaiyun.com/chenhao0428/article/details/51436837写的:
package com.example.xposedandriod; import static de.robv.android.xposed.XposedHelpers.findClass; import java.lang.reflect.Field; import android.app.Activity; import android.hardware.Sensor; import android.util.Log; import android.util.SparseArray; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class WeiXinSport extends Activity implements IXposedHookLoadPackage { /** * @param args */ private static int stepCount = 1; @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable{ if(!loadPackageParam.packageName.equals("com.tencent.mm")){//过滤来自微信的请求 return; } //hook了andriod.hardware.SystemSensorManager$SensorEventQueue这个类中的dispatchSensorEvent这个方法 final Class sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue",loadPackageParam.classLoader); XposedBridge.hookAllMethods(sensorEL,"dispatchSensorEvent", new XC_MethodHook(){ @SuppressWarnings("unchecked") @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable{ ((float[]) param.args[1])[0] = ((float[]) param.args[1])[0] + 1200*stepCount;//计数传感器将步数返回微信运动之前被修改 stepCount++; XposedBridge.log("stepCount"+stepCount); Field field = param.thisObject.getClass().getDeclaringClass().getDeclaredField("sHandleToSensor"); field.setAccessible(true); //便于调试,将传感器的一些数据打印了出来 int handle = (Integer)param.args[0]; Sensor sensor = ((SparseArray ) field.get(0)).get(handle); XposedBridge.log("sensor = " + sensor); } }); } }