本帖最后由 tyc600 于 2024-11-15 08:18 编辑
如下图所示我已经成功hook到activity后注册了一个动态广播来响应外部类的调用。
代码1:hook到activity对象
[Java] 纯文本查看 复制代码 import android.app.Activity;
import android.os.Bundle;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
public class MyRecHook {
public MyRecHook() {
XposedBridge.log("MyHook start MyRecHook");
XposedHelpers.findAndHookMethod(Activity.class, "onCreate", new Object[]{Bundle.class, new MyRecHook$1(this)});
}
}
代码2:内部类,注册动态广播
[Java] 纯文本查看 复制代码 import android.app.Activity;
import android.content.IntentFilter;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
class MyRecHook$1 extends XC_MethodHook {
final MyRecHook this$0;
MyRecHook$1(MyRecHook myRecHook) {
this.this$0 = myRecHook;
}
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
super.beforeHookedMethod(methodHookParam);
}
protected void afterHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
super.afterHookedMethod(methodHookParam);
try {
XposedBridge.log("MyHook start hook");
((Activity) methodHookParam.thisObject).registerReceiver(new MyRecHook$1$1(this, methodHookParam), new IntentFilter("my.screen.action"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码3:内部类,响应外部对activity的调用
[Java] 纯文本查看 复制代码 import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import github.xposed.MyRecHook;
class MyRecHook$1$1 extends BroadcastReceiver {
final MyRecHook.1 this$1;
final XC_MethodHook.MethodHookParam val$param;
MyRecHook$1$1(MyRecHook.1 r1, XC_MethodHook.MethodHookParam methodHookParam) {
this.this$1 = r1;
this.val$param = methodHookParam;
}
@Override
public void onReceive(Context context, Intent intent) {
int intExtra = intent.getIntExtra("screen", 0);
XposedBridge.log(context.getPackageName() + "收到屏幕旋转事件" + intExtra);
((Activity) this.val$param.thisObject).setRequestedOrientation(intExtra);
}
}
为了避免频繁的注册动态广播【因为实际上这个activity只在部分需要的场合才需要被调用,显然每次都hook到对象都注册动态广播对系统资源造成负担】,后来我尝试将获取到的activity对象保存为全局变量,
[Java] 纯文本查看 复制代码 import android.app.Activity;
import android.content.IntentFilter;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
class MyRecHook$1 extends XC_MethodHook {
final MyRecHook this$0;
MyRecHook$1(MyRecHook myRecHook) {
this.this$0 = myRecHook;
}
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
super.beforeHookedMethod(methodHookParam);
}
protected void afterHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
super.afterHookedMethod(methodHookParam);
try {
XposedBridge.log("MyHook start hook");
new IntentFilter("my.screen.action");
【★★★修改了此行★★★】AppEnv.j().setActivity((Activity) methodHookParam.thisObject);
} catch (Exception e) {
e.printStackTrace();
}
}
}
用于存储activity对象,并响应外部调用类如下,但是运行后报错如下【[Error: ui.requestScreenOrientation(0): Attempt to invoke virtual method 'void android.app.Activity.setRequestedOrientation(int)' on a null object reference],】,如何保存activity为全局变量还请路过的大虾指点一下。
[Java] 纯文本查看 复制代码 import android.app.Activity;
import java.lang.ref.WeakReference;
public class AppEnv {
private static final AppEnv o = new AppEnv$1();
private WeakReference<Activity> myactivity;
public static AppEnv j() {
return o;
}
public final void setRequestedOrientation(int i) {
WeakReference<Activity> weakReference = this.myactivity;
if (weakReference != null) {
weakReference.get().setRequestedOrientation(i);
}
}
public final void setActivity(Activity activity) {
WeakReference<Activity> weakReference = this.myactivity;
if (weakReference != null) {
weakReference.clear();
}
this.myactivity = new WeakReference<>(activity);
}
}
内部类赋值操作如下:
[Java] 纯文本查看 复制代码 import android.app.Activity;
class AppEnv$1 extends AppEnv {
AppEnv$1() {
setActivity((Activity) null);
}
}
|