Got asked this today in an Android interview. I answered the usual, you know, intent + startActivity, etc. Interviewer then asked more pointedly,
"Yes, but where is it actually instantiated? You don't call new Activity anywhere".
Which now that I think about it, I don't really know. He hinted that it used Java reflection, but I dont have a lot of experience with that, and I've only used it to access some variables in the Android SDK.
Can someone explain how Activities are instantiated using reflection, and why? Bonus points for insight into what value the interviewer saw in knowing this.
We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.
In object-oriented programming languages such as Java, reflection allows inspection of classes, interfaces, fields and methods at runtime without knowing the names of the interfaces, fields, methods at compile time. It also allows instantiation of new objects and invocation of methods (Wikipedia). Object foo = Class.
Android supports reflection. Once you've got a prototype running, you can benchmark and determine your bottlenecks. If its reflection, then consider trying to cache interfaces and such to make it a one-off cost, rather than continually resolving the same interfaces from the same instances repeatedly.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
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(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With