Kotlin书写动态代理method.invoke(iam, *args) must not be null
Posted csdn用户R
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin书写动态代理method.invoke(iam, *args) must not be null相关的知识,希望对你有一定的参考价值。
文章目录
问题
1.动态代理使用Kotlin书写报错
描述
Process: com.y.hookdemo, PID: 24014
java.lang.IllegalArgumentException: method android.app.IActivityManager$Stub$Proxy.getActivityDisplayId argument 1 has type android.os.IBinder, got java.lang.Object[]
at java.lang.reflect.Method.invoke(Native Method)
at com.y.hookdemo.HookUtil$HookInvocationHandler.invoke(HookUtil.kt:121)
- kotlin书写:
private class HookInvocationHandler(private val iam: Any): InvocationHandler
@Throws(Throwable::class)
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any
if (method.name.contains("startActivity"))
Log.e("Hook", "IActivityManager动态代理的invoke方法,伪装intent")
for (i in args.indices)
if (args[i] is Intent)
val intent = args[i] as Intent
val proxyIntent = Intent(mContext, ProxyActivity::class.java)
proxyIntent.putExtra("intent", intent)
args[i] = proxyIntent
break
return method.invoke(iam, args)
报错在 return method.invoke(iam, args) 这一行,用java写正常执行
- java书写:
private class HookInvocationHandler implements InvocationHandler
private Object iam;
private HookInvocationHandler(Object iam)
this.iam = iam;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
if (method.getName().contains("startActivity"))
Log.e("Hook", "IActivityManager动态代理的invoke方法,伪装intent");
for (int i = 0; i < args.length; i++)
if (args[i] instanceof Intent)
Intent intent = (Intent) args[i];
Intent proxyIntent = new Intent(mContext, ProxyActivity.class);
proxyIntent.putExtra("intent", intent);
args[i] = proxyIntent;
break;
return method.invoke(iam, args);
将java通过as转为kotlin,这行变为
return method.invoke(iam, *args)
第二个参数变为*args,依旧报错
com.y.hookdemo E/AndroidRuntime: Error reporting crash
java.lang.IllegalStateException: method.invoke(iam, *args) must not be null
at com.y.hookdemo.HookUtil$HookInvocationHandler.invoke(HookUtil.kt:121)
at java.lang.reflect.Proxy.invoke(Proxy.java:913)
思考
@CallerSensitive
// Android-changed: invoke(Object, Object...) implemented natively.
@FastNative
public native Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
反射api中Method的invoke方法接收可变长参数,在java中允许数组赋值给可变长参数Object… args,Kotlin中,数组是array,可变长参数类型是vararg,类型不一致,所以method.invoke(iam, args)
,是两个参数,第二个参数是数组,实际方法需要多个参数,第二个参数是IBinder,所以报第一个错。
Kotlin中数组转为可变长参数,是通过前面加*,所以as把java转为kotlin后,变为method.invoke(iam, *args)
,参数正确,但依旧报第二个错.
???
解决
解决毛,谷歌吹个毛的java和kotlin可以一起用,改用java写了
kotlin书写时,返回值是Any,方法可能是没有返回值的,所以修改为Any?,然后修改
private class HookInvocationHandler(private val iam: Any): InvocationHandler
@Throws(Throwable::class)
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any?
if (method.name.contains("startActivity"))
Log.e("Hook", "IActivityManager动态代理的invoke方法,伪装intent")
for (i in args.indices)
if (args[i] is Intent)
val intent = args[i] as Intent
val proxyIntent = Intent(mContext, ProxyActivity::class.java)
proxyIntent.putExtra("intent", intent)
args[i] = proxyIntent
break
val res = method.invoke(iam, *args)
Log.e("------a1:$method.name",args.size.toString())
Log.e("res = ",res?.toString() + "--")
Log.e("returnType:",method.genericReturnType.typeName)
return if("void" == method.genericReturnType.typeName) Unit else res
正常运行
- 新的问题
java书写时返回值为Object,执行没有返回值的method时,为什么可以
以上是关于Kotlin书写动态代理method.invoke(iam, *args) must not be null的主要内容,如果未能解决你的问题,请参考以下文章