我正在尝试使用反射来访问ActivityView类的私有最终字段,该类在Android AOSP中是隐藏的。我使用反射创建了一个ActivityView对象,该对象内部具有SurfaceView,并且需要有一个回调来告诉我何时创建表面。
val activityViewClass = Class.forName("android.app.ActivityView")
val activityView = activityViewClass.getConstructor(Context::class.java).newInstance(this)
然后,有两个选项可以访问该回调:
1.从类中直接访问私有的最终回调字段。
所以我尝试访问抛出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) { } }
这正是我所需要的。但是由于它是一个抽象类,所以无法实例化它。而且我也无法扩展它,因为它是隐藏的。
有什么想法如何访问该私有字段或如何使用反射来扩展隐藏的抽象类?
最佳答案
系统应用程序无需执行任何操作即可访问隐藏的类。如果可以访问ActivityView,则还可以访问StateCallBack。
您应该定义状态
private StateCallback mStateCallback = new StateCallback() {
@Override
public void onActivityViewReady(ActivityView view) {
Log.v(LOG_TAG, "onActivityViewReady");
}
@Override
public void onActivityViewDestroyed(ActivityView view) {
Log.v(LOG_TAG, "onActivityViewDestroyed");
}
@Override
public void onTaskMovedToFront(ActivityManager.StackInfo stackInfo) {
Log.v(LOG_TAG, "onTaskMovedToFront");
}
};
然后像这样设置
mActivityView = findViewById(R.id.activity_view);
mActivityView.setCallback(mStateCallback);