[Android-3.3 topic] talk about your understanding of Application

Keywords: shell

Inspection content:

  • Understand the role of Application (primary)
  • Familiar with class inheritance and life cycle of Application (intermediate)
  • In depth understanding of Application initialization principle (Advanced)

What is the role of Application?

(first of all, it is a system component with a long life cycle. As long as it is applied in, it is in.)

  • Save global variables in user process
  • Initialize operation
  • Provide application context

Application features:

  • Live long
  • Born early (Application creation is in front of the four major components)
  • Application follows the application, not the process. If the process creates several applications, there will be several applications

Inheritance relationship of Application class

  • Application extends ContextWrapper
  • ContextWrapper extends Context
class Application extends ContextWrapper implements XXX{
}
public class Context Wrapper extends Context{
  Context mBase;
  public ContextWrapper(Context base){
    mBase = base;
  }
  protected void attachBaseContext(Context base){
    mBase = base;
  }
}

The life cycle of Applicatoin

How to initialize Application?

Process entry function:

public static void main(String[] args){
  Looper.prepareMainLooper();
  ActivityThread thread = new ActivityThread;
  //Mainly used for application end-to-end AMS Report
  thread.attach(false);
  Looper.loop();
  throw new RuntimeExceptiom("Main thread loop unexpectedly exited");
}

private void attach(){
  //Get Binder object of ActivityManager
  final IActivityManager mgr = ActivityManagerNative.getDefault();
  try{
    //
    mgr.attachApplication(mAppThread);
  }catch(RemoteException ex){
    //Ignore
  }
}

//Run on AMS:
public final void attachApplication(IApplicationThread thread){
  synchronized(this){
    attachApplicationLocked(thread, callingPid);
  }
}
//Run on AMS:
boolean attachApplicationLocked(IApplicationThread thread, ...){
  ......
  thread.bindApplication(...);
  ......
}
//Application side: (binder thread)
public final void bindApplication(...){
  AppBindData data = new AppBindData();
  ......
  sendMessage(H.BIND_APPLICATION, data);
}
//The application side processes the function of bindApplication in the main thread:
private void handleBindApplication(AppBindData data){
  //Get information describing the app installation package
  data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
  //Create Application object
  Application app = data.info.makeApplication(...);
  //Call app.onCreate
  mInstrumentation.callApplicationOnCreate(app);
}

public Application makeApplication(...){
  if(mApplication != null){
    return mApplication;
  }
  ContextImpl appContext = ContextImpl.createAppContext(...);
  app = mActivityThread.mInstrumentation.newApplication(...);
  return app;
}

Application newApplicatoin(ClassLoader cl, String className, Context context){
  //Load a class
  return newApplication(cl.loadClass(className), context);
}

Static Application newApplication(Class<?> clazz, Context context){
  //Then call the constructor of this class to create a Application object.
  Application app = (Application)clazz.newInstance();
  //Finally, attach context to app
  app.attach(context);
  return app;
}

//Although the Application is a Context, it is just an empty shell. What really works is a member named mBase Context
final void attach(Context context){
  attachBaseContext(context);  //Assign value to mBase
}

Key functions:

  • new Application()
  • application.attachBaseContext()
  • application.onCreate()

Attention:

1. Do not perform time-consuming operations in Application's lifecycle callback

boolean attachApplicationLocked(IApplicationThread thread, ...){
  ..
  thread.bindApplication(...);
  ...
  //Components of pending after bindApplication:
  mStackSupervisor.attachApplicationLocked(...);
  mServices.attachApplicationLocked(app, processName);
  sendPendingBroadcastLocked(app);
  ...
}

After bindApplication processes the pending components, including Activity, Service, Broadcast, etc., its Application didn't need to be started when the components were started. Now that the Application process is started and the Application is initialized, the components to be started can be processed. The start-up operations of these components are finally performed in the Application process, such as acti The life cycle of vity is invoked in the UI thread of Application. If the Application takes too long, it will delay the start of the Application components.

2. A bug generated when application uses static variables


There is a static variable name in the Application. MainActivity will set the name. After setting, it will jump to TestActivity and Test will read the name. There is no problem in normal conditions. But if the Application is switched to the background here, after a period of time, the system will kill the Application due to insufficient memory, and then when the Application is switched back, the system will rebuild the Application, including rebuilding the Application and resuming the TestActivity. But at this time, the name in the Application is not initialized, and the name obtained by TestActivity is null, so an exception may occur.

Return: talk about your understanding of Application

  • What is its function?
    a) Save global variables in user process
    b) Initialize operation
    c) Provide application context
  • Its class inheritance relationship, life cycle, and call sequence of life cycle
  • Its initialization principle
112 original articles published, praised 27, visited 100000+
Private letter follow

Posted by trollll on Sat, 22 Feb 2020 23:44:46 -0800