How is an Android activity instantiated (using reflection)?

前端 未结 4 537
时光说笑
时光说笑 2020-12-24 03:41

Got asked this today in an Android interview. I answered the usual, you know, intent + startActivity, etc. Interviewer then asked more pointedly,

\"Ye

4条回答
  •  忘掉有多难
    2020-12-24 04:25

    When an app's launcher icon is clicked on homescreen, following event happens under the android system :

    • Homescreen/Launcher app sends an intent to start an activity using startActivity()(startActivity() is binder call to ActivityManager)
    • Activity Manager sends a process fork request using a socket to Zygote.
    • Zygote forks a new VM instance that loads ActivityThread(Activity thread manages the execution of the main thread in an application process, scheduling and executing activities, broadcasts, and other operations on it as the activity manager requests.).
    • ActivityThread has real main() for an app.
    • ActivityThread calls the app's onCreate().

    Hence ActivityThread is responsible for instantiating Activity(inside performLaunchActivity method)

    Explanation :

    If you observe the stacktrace :

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

    Code where new activity is instantiated :

    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(class will be instantiated for you before any of the application code)

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

提交回复
热议问题