【发布时间】:2020-06-04 02:41:16
【问题描述】:
我正在尝试使用反射来访问隐藏在 Android AOSP 中的 ActivityView 类的私有 final 字段。我使用反射创建了一个 ActivityView 对象,它内部有一个 SurfaceView,我需要一个回调来告诉我何时创建表面。
val activityViewClass = Class.forName("android.app.ActivityView")
val activityView = activityViewClass.getConstructor(Context::class.java).newInstance(this)
然后,有两个选项可以访问该回调:
1.从类中直接访问私有 final 回调字段。
所以我尝试访问抛出 java.lang.NoSuchFieldException 的 mSurfaceCallback 字段。
val field = activityView::class.java.getDeclaredField("mSurfaceCallback")
如果我尝试访问任何其他私有字段,我会收到相同的错误。
如果我打电话给activityView::class.java.declaredFields,我会得到一个空列表。
我在 Java 和 Kotlin 中尝试了 kotlin-reflect 库,但没有成功。
我还尝试了https://github.com/ronmamo/reflections 库进行反射,我得到了相同的结果。
2。将 ActivityView.StateCallback 设置为活动视图。
ActivityView 有一个 StateCallback 对象,如下所示:
/** Callback that notifies when the container is ready or destroyed. */
public abstract static class StateCallback {
/**
* Called when the container is ready for launching activities. Calling
* {@link #startActivity(Intent)} prior to this callback will result in an
* {@link IllegalStateException}.
*
* @see #startActivity(Intent)
*/
public abstract void onActivityViewReady(ActivityView view);
/**
* Called when the container can no longer launch activities. Calling
* {@link #startActivity(Intent)} after this callback will result in an
* {@link IllegalStateException}.
*
* @see #startActivity(Intent)
*/
public abstract void onActivityViewDestroyed(ActivityView view);
/**
* Called when a task is moved to the front of the stack inside the container.
* This is a filtered version of {@link TaskStackListener}
*/
public void onTaskMovedToFront(ActivityManager.StackInfo stackInfo) { }
}
这正是我需要的。但由于它是一个抽象类,我无法实例化它。而且我也无法扩展它,因为它是隐藏的。
任何想法如何访问该私有字段或如何使用反射扩展隐藏的抽象类?
【问题讨论】:
-
您使用的是哪个 SDK 版本?
-
@ihsan.gaozp 我用的是安卓28
-
developer.android.com/distribute/best-practices/develop/… 请检查这个文档,谷歌有限制反射。但也有一些方法可以解决这个问题。
-
androidxref.com/9.0.0_r3/xref/art/runtime/jni_internal.cc#88 这是系统限制您访问的方式。因此,您可以使用 android.shareduid="android.uid.system" 使您的应用成为系统应用
-
非常感谢@ihsan.gaozp。该应用程序是系统应用程序,所以我会尝试一下。
标签: java android reflection