接下来深海会和大家逐步分享分析Android插件化相关的东西
要了解插件化首先要具备三个前提条件:
1.Android 系统源码阅读于理解
2.Java 反射机制
3.Hook技术
今天咱们就一起分析Hook的相关知识
一.Hook是什么?
在事件执行的过程中截获并监控事件的执行流,将自身的代码融入其执行流中
二.简单举例: Hook 修改 View.OnClickListener 事件
首先阅读系统类View的源码,找到Hook点击事件的关键代码
看点击事件的方法:这边传入的事件赋给了ListenerInfo对象的mOnClickListener接口实例
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
追溯该方法:该方法返回了ListenerInfo对象
@UnsupportedAppUsage
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
}
mListenerInfo = new ListenerInfo();
return mListenerInfo;
}
然后整理结构:
得出Hook路线:
1.拿到View对象中的mListenerInfo对象
2.然后拿到mOnClickListener接口实例
3.对该实例进行二次封装后替换该实例
具体实现代码:
/*
*作者:赵星海
*时间:2020/6/23 9:51
*用途:Hook简单举例(View点击事件)
*/
public static void hookOnClickListener(View view) throws Exception {
// 第一步:反射得到 ListenerInfo 对象
Method getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");
getListenerInfo.setAccessible(true);
Object listenerInfo = getListenerInfo.invoke(view);
// 第二步:得到原始的 OnClickListener事件方法
Class<?> listenerInfoClz = Class.forName("android.view.View$ListenerInfo");
Field mOnClickListener = listenerInfoClz.getDeclaredField("mOnClickListener");
mOnClickListener.setAccessible(true);
View.OnClickListener originOnClickListener = (View.OnClickListener) mOnClickListener.get(listenerInfo);
// 第三步:用 Hook代理类 替换原始的 OnClickListener
View.OnClickListener hookedOnClickListener = new HookedClickListener(originOnClickListener);
mOnClickListener.set(listenerInfo, hookedOnClickListener);
}
public static class HookedClickListener implements View.OnClickListener {
private View.OnClickListener origin;
public HookedClickListener(View.OnClickListener origin) {
this.origin = origin;
}
@Override
public void onClick(View v) {
// Toast.makeText(v.getContext(), "你的点击事件被赵星海劫持了!", Toast.LENGTH_SHORT).show();
if (origin != null) {
origin.onClick(v);
}
}
}
好了今天的分享就到这里哦,关于上诉内容,有任何的疑惑或者建议欢迎评论区沟通交流哦~
深海特别愿意和大家一起互相学习互相进步