【问题标题】:How is an Android activity instantiated (using reflection)?如何实例化 Android 活动(使用反射)?
【发布时间】:2015-11-09 20:49:44
【问题描述】:

今天在一次 Android 采访中被问到这个问题。我回答的是通常的,你知道的,intent + startActivity 等。然后面试官问得更尖锐,

“是的,但它实际上在哪里实例化?你不叫 new 随时随地活动”。

现在回想起来,我真的不知道。他暗示它使用了Java反射,但我没有太多经验,我只用它来访问Android SDK中的一些变量。

谁能解释一下如何使用反射来实例化活动,以及为什么?深入了解面试官在了解这一点时看到了什么价值,可以获得奖励积分。

【问题讨论】:

  • 我认为面试官的价值在于他可以看到你不仅可以使用框架,而且对所有事情发生的原因和地点感兴趣。但是,即使您还没有检查过,您对这些意想不到的问题的反应也会向面试官展示您如何应对意外情况以及您能以多快的速度想出可能的答案。

标签: java android reflection


【解决方案1】:

当在主屏幕点击应用的启动器图标时,在android系统下会发生以下事件:

  • Homescreen/Launcher 应用程序使用 startActivity() 发送启动 Activity 的意图(startActivity() 是对 ActivityManager 的活页夹调用)
  • 活动管理器使用套接字向 Zygote 发送进程分叉请求。
  • Zygote fork 一个新的 VM 实例,该实例加载 ActivityThread(Activity 线程管理应用程序进程中主线程的执行,根据 Activity 管理器的请求调度和执行其上的活动、广播和其他操作。)。
  • ActivityThread 对应用程序具有真正的 main()。
  • ActivityThread 调用应用的 onCreate()。

因此 ActivityThread 负责实例化 Activity(在 performLaunchActivity 方法中)

解释:

如果你观察堆栈跟踪:

android.app.Instrumentation.newActivity(Instrumentation.java:1021)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)

实例化新活动的代码:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ... //More code
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
    ... //More code
    return activity;
}

Instrumentation.java(类将在任何应用程序代码之前为您实例化)

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

【讨论】:

    【解决方案2】:

    检查构造函数方法路径的简单方法是创建一个临时项目,覆盖Activity 中的构造函数并在那里放置断点。

    您应该能够浏览所有代码并找到您想要的内容。

    【讨论】:

      【解决方案3】:

      只要你不是在面试 Android 系统开发人员(内核黑客,...),答案很简单:这是一个普通 Android 开发人员不需要关心的 Android 框架的实现细节,因为抽象和层原理,在极少数情况下您确实需要了解它。

      【讨论】:

        【解决方案4】:

        Android 核心负责管理 de Activity 的实例化,并将其管理到他的 Activity 生命周期中。

        android 系统负责以正确的顺序调用您可以在类中控制的所有事件,将活动添加到堆栈以及许多其他事情。

        当您调用 startActivity 时,Android 核心会取得控制权并创建一个 Activity 实例(如果匹配,则重用之前的实例)并开始调用 Activity 生命周期事件

        您可以在此处查看:http://developer.android.com/reference/android/app/Activity.html in Activity Lifecycle 部分

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多