android (three), the working principle of Activity

When a new application is started, startActivity is first called to start the Activity. At this time, the process has not been created yet, a new process will be forked and an instance of ActivityThread will be created;


Activity creation process


   Activity in Android is just a controller, responsible for message transfer between user operations and View. Activity creates a Window (setContentView) instance that allows the user to place the UI, but it is not a view itself, nor does it do any operation on the UI.

   Window is a top-level window class. As a performance strategy, it is usually added to Window Manager as a view. Each Activity instance corresponds to a Window instance. Window is just an abstract class, and its implementation class is android.policy.PhoneWindow , which is a very important class .

  Usually start an Activity will call the startActivity () method, the startActivity method internally through a class called Instrumentation to start the Activity.

  Instrumentation is a tool class for applications to manage Activity. It provides methods to control the full life cycle of activity. When an application is created, it will first create an Instrumentation instance , andInstrumentation will start Activity by calling execStartActivities. 

 Activity creation steps are as follows:

   Step 1: Send the creation information to Instrumentation by Context.
   The second step: Instrumentation then forwards the information to ActivityManagerService.
   The third step: After ActivityManagerService completes the related recording work of the Activity, it sends the creation information to the ApplicationThread.
   The fourth part: ActivityThread calls ( Instrumentation ) Activity creation method and executes the life cycle of Activity.

 The above four parts are simplified information transfer process between framework and application, actual operation will be very complicated.


  The method body of execStartActivities is as follows

 public void execStartActivities(Context who, IBinder contextThread,
1431            IBinder token, Activity target, Intent[] intents, Bundle options) {
1432        IApplicationThread whoThread = (IApplicationThread) contextThread;
1433        if (mActivityMonitors != null) {
1434          ····
1447        }
1448        try {
1449           ·····
1454            int result = ActivityManagerNative.getDefault()
1455                .startActivities(whoThread, intents, resolvedTypes, token, options);
1456            checkStartActivityResult(result, intents[0]);
1457        } catch (RemoteException e) {
1458        }
1459    }


  An IApplicationThread object is passed in to this method . The IApplicationThread class is an internal class of ActivityThread. Because it is a subclass of Binder, the main job of this class is to communicate across processes. There is such an ActivityManagerNative.getDefault() code inside the method, which actually returns an instance of ActivityManagerService. ActivityManagerService calls the startActivity method. After ActivityManagerService records the Activity information, it sends a command to create an Activity object to IApplicationThread . IApplicationThread is the interface for ActivityThread's external communication .

  After IApplicationThread receives the activity creation command from ActivityManagerService, it will relay the creation message to ActivityThread through the Handler . After receiving the information , ActivityThread calls its own handleLaunchActivity() method.

  The main function of this method is to create the Activity object and the Application object, and execute the attach method of the Activity, and also call the onCreate method in the Activity life cycle. The main content of the handleLaunchActivity method body is as follows : 

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2233        Activity a = performLaunchActivity(r, customIntent);此方法内部调用了Activity的attach方法
2235        if (a != null) {
2236            r.createdConfig = new Configuration(mConfiguration);
2237            Bundle oldState = r.state;
2238            handleResumeActivity(r.token, false, r.isForward,
2239                    !r.activity.mFinished && !r.startsNotResumed);  
2293    }


  The main work of the attach method of Activity is to create Window and bind WindowManger instance, there is also a Window.setCallback(), this method is mainly to allow Activity to receive user touch events and so on.

               mWindow = PolicyManager.makeNewWindow(this);
5191        mWindow.setCallback(this);
5192        mWindow.getLayoutInflater().setPrivateFactory(this);
5214        mWindow.setWindowManager(
5215                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
5216                mToken, mComponent.flattenToString(),
5217                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
5218        if (mParent != null) {
5219            mWindow.setContainer(mParent.getWindow());
5220        }
5221        mWindowManager = mWindow.getWindowManager();

   The WindowManger has been created before the Activity executes the onCreate method, and the setContentView method is generally called in oncreate, which completes the addition of the View.

1948    public void setContentView(View view) {
1949        getWindow().setContentView(view);
1950        initActionBar();
1951    }

 
 

  After the creation of the Activity is performed, the handleResumeActivity method is executed . This method is mainly to add the DectorView of the activity to the WindowMnager. This process is the operation of displaying the view in the setContentView to the screen.
 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2798            boolean reallyResume) {
2803        ActivityClientRecord r = performResumeActivity(token, clearHide);
2804
2805        if (r != null) {
2806          ···········
2827            if (r.window == null && !a.mFinished && willBeVisible) {
2828                r.window = r.activity.getWindow();
2829                View decor = r.window.getDecorView();
2830                decor.setVisibility(View.INVISIBLE);
2831                ViewManager wm = a.getWindowManager();
2832                WindowManager.LayoutParams l = r.window.getAttributes();
2833                a.mDecor = decor;
2834                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2835                l.softInputMode |= forwardBit;
2836                if (a.mVisibleFromClient) {
2837                    a.mWindowAdded = true;
2838                    wm.addView(decor, l);
2839                }
2895            // Tell the activity manager we have resumed.
2896            if (reallyResume) {
2897                try {
2898                    ActivityManagerNative.getDefault().activityResumed(token);
2899                } catch (RemoteException ex) {
2900                }
2901           
2904           ·····
2912    }
  
   
   

Guess you like

Origin blog.csdn.net/jiabailong/article/details/50972742