Java回调函数与什么是hook
Java回调函数Demo:
public class HookUtil { private static HookUtil hookUtil ; private HookUtil(){} public static HookUtil getInstance(){ if(hookUtil == null){ hookUtil = new HookUtil(); } return hookUtil; } public interface HookUtilCallback{ void backSuccess(int code); void backFail(int code); } private HookUtilCallback hookUtilCallback = null; public void setHookUtilCallback(HookUtilCallback callback){ hookUtilCallback = callback; } public void doSomething(int code){ if(hookUtilCallback != null){ hookUtilCallback.backFail(code); } } }
public class DemoT1 {
//控件监听回调 --简单版
public demoT1_ClickListener mDemoT1_clickListener;
public interface demoT1_ClickListener {
void T1Click();
}
public void setDemoT1_clickListener(demoT1_ClickListener demoT1_clickListener){
demoT1_clickListener = mDemoT1_clickListener;
}
//回调函数--demo版
private interface Response {
void onSuccess(String data);
void onFailed(String prompt);
}
private static String doSomething(){
try {
//......
Thread.sleep(5000); //模拟耗时操作(如网络请求),操作正常返回"Success","Success"表示有效的数据
return "Success";
} catch (InterruptedException ex) {
Logger.getLogger(DemoT1.class.getName()).log(Level.SEVERE, null, ex);
//操作出现问题返回"Failed","Failed"包含错误提示,如错误码等
return "Failed";
}
}
// 使用回调函数操作
private static void callbackDoSomething(Response response){
try {
Thread.sleep(5000);
response.onSuccess("Success");
} catch (InterruptedException ex) {
Logger.getLogger(DemoT1.class.getName()).log(Level.SEVERE, null, ex);
response.onFailed("Failed");
}
}
public static void main(String[] args) {
//实例
DemoT1.callbackDoSomething(new Response() {
@Override
public void onSuccess(String data) {
}
@Override
public void onFailed(String prompt) {
}
});
}
}
HOOK:什么是hook?
hook (钩子) -->在java中它表示在事件到达终点前进行拦截或监控的一种行为.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** *实现hook我们必须要知道java的反射和动态代理 */ public class HookDemo { /** * 反射是java的查看、检测、修改自身的一种行为。 *在编译阶段,编译器将我们编写的java文件编译成.class文件。 * 而在运行期,jvm又将.class文件通过类加载器ClassLoader加载一个类对应的Class对象到内存当中。 * 通过修改Class对象,达到我们查看、检测、修改自身的行为。 */ Class mClass; { try { /* * Constructor constructor = mClass.getConstructor(); 拿到构造函数 * DemoT1 t1 = (DemoT1) constructor.newInstance(DemoT1.class);获取新实例 * * 同理,通过class类对象,可以获取对象的方法。动态代理中需要在方法拦截。 Methods method[] = mClass.getDeclaredMethods(); * 获取对象的域, Field[] fields = mClass.getDeclaredFields(); * * */ mClass = Class.forName( "com.android.myapplication.demo1.DemoT1" ); Constructor constructor = mClass.getConstructor(); DemoT1 t1 = (DemoT1) constructor.newInstance(DemoT1. class ); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } |
拦截Android的button控件的监听-hook
public class MainActivity extends AppCompatActivity {
TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.text);
mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("tww", "origin click");
}
});
hookOnClickListener(mTextView);
}
private void hookOnClickListener(View view) {
try {
// 得到 View 的 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);
// 用自定义的 OnClickListener 替换原始的 OnClickListener
View.OnClickListener hookedOnClickListener = new HookedOnClickListener(originOnClickListener);
mOnClickListener.set(listenerInfo, hookedOnClickListener);
} catch (Exception e) {
Log.e("tww", "hook clickListener failed!", e);
}
}
public class HookedOnClickListener implements View.OnClickListener {
private View.OnClickListener origin;
HookedOnClickListener(View.OnClickListener origin) {
this.origin = origin;
}
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "hook click", Toast.LENGTH_SHORT).show();
Log.e("tww", "Before click, do what you want to to.");
if (origin != null) {
origin.onClick(v);
}
Log.e("tww", "After click, do what you want to to.");
}
}
}
https://www.jianshu.com/p/4f6d20076922
startActivity()--->
分类:
Android
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!