Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is an Android activity instantiated (using reflection)?

Tags:

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.

like image 589
Eric S. Avatar asked Nov 09 '15 20:11

Eric S.


People also ask

How do you instantiate an object using a reflection?

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.

How do you use reflection on Android?

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.

Does reflection work in Android?

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.

What is reflection Java?

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.


1 Answers

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(); } 
like image 183
abhishesh Avatar answered Oct 10 '22 02:10

abhishesh