使用反射从隐藏的AOSP类获取私有字段

时间:2019-06-10 07:14:40

标签: java android reflection

我正在尝试使用反射来访问ActivityView类的私有final字段,该类隐藏在Android AOSP中。我使用反射创建了一个ActivityView对象,该对象内部具有 SurfaceView ,并且需要有一个回调函数来告诉我何时创建表面。

val activityViewClass = Class.forName("android.app.ActivityView")
val activityView = activityViewClass.getConstructor(Context::class.java).newInstance(this)

然后,有两个选项可以访问该回调:

1。直接从类中访问私有的最终回调字段。

所以我尝试访问 mSurfaceCallback 字段,该字段抛出 java.lang.NoSuchFieldException

val field = activityView::class.java.getDeclaredField("mSurfaceCallback")

如果我尝试访问任何其他私有字段,则会遇到相同的错误。

如果我致电activityView::class.java.declaredFields,我会得到一个空名单。

我在Kotlin的Java中使用 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) { } }

这正是我所需要的。但是由于它是一个抽象类,所以无法实例化它。而且我也无法扩展它,因为它是隐藏的。

有什么想法如何访问该私有字段或如何使用反射来扩展隐藏的抽象类?

1 个答案:

答案 0 :(得分:0)

系统应用程序无需执行任何操作即可访问隐藏的类。如果可以访问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);