android (三)、Activity工作原理

启动一个新的应用程序时,首先会调用startActivity来启动Activity,此时进程还没有创建,会fork一个新进程,并创建ActivityThread实例;

 

Activity的创建过程

 

   android中Activity只是一个控制器,负责用户操作和View之间传递消息,Activity创建一个能让用户摆放UI的Window(setContentView)实例,但它本身并不是一个view,也不对UI做任何操作。

   Window是一个顶级窗口类,它作为一种表现策略,通常当作view添加到Window Manager中,每个Activity实例都对应一个Window实例。Window只是一个抽象类,它的实现类为android.policy.PhoneWindow,是个相当重要的类

  通常启动一个Activity会调用startActivity()方法,startActivity方法内部通过一个名叫Instrumentation的类来启动Activity。

  Instrumentation是应用程序管理Activity的工具类,他提供了控制了activity的全生命周期的方法,应用创建的时,会先创建Instrumentation 实例Instrumentation通过调用execStartActivities来启动Activity 

 Activity创建步骤如下:

   第一步:由Context发送创建信息到Instrumentation。
   第二步:Instrumentation再转发信息到ActivityManagerService。
   第三步:ActivityManagerService做好Activity的相关记录工作后,发送创建信息到ApplicationThread。
   第四部:ActivityThread调用(Instrumentation)Activity的创建方法,并执行Activity的生命周期。

 以上四部是简化过的framework和应用之间信息传递的过程,实际操作会很复杂。

 

  execStartActivities的方法体如下


 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    }

 

  这个方法中传入了一个IApplicationThread对象,IApplicationThread类是ActivityThread的内部类,因为它是Binder的子类,所以这个类的主要工作就是跨进程通信。 方法内部有这么一句ActivityManagerNative.getDefault()代码,返回的其实是ActivityManagerService实例。ActivityManagerService调用startActivity方法,ActivityManagerService做好Activity信息记录后,向IApplicationThread发送创建Activity对象的命令,IApplicationThread是ActivityThread对外通信的接口

  IApplicationThread收到ActivityManagerService的创建Activity的命令后,会通过Handler向ActivityThread转达创建消息,ActivityThread收到信息后调用自身的handleLaunchActivity()方法。

  这个方法的主要作用就是创建Activity对象和Application对象,并且执行Activity的attach方法,还调用了Activity生命周期中的onCreate方法。handleLaunchActivity方法体的主要内容如下 

 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    }
 

 

  Activity的attach方法主要工作就是创建Window和绑定WindowManger实例,还有一个Window.setCallback(),这个方法主要就是让Activity能够收到用户的触摸事件等。

 

               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();


   在Activity执行onCreate方法前已经已经创建了WindowManger,在oncreate中一般会调用setContentView方法,这样就完成了View的添加。

 

 

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

 

 


 

  在执行完Activity的创建后,又执行了handleResumeActivity方法,该方法主要是将activity的DectorView添加到WindowMnager中,这个过程也就是把setContentView中的view显示到屏幕上的操作。
 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    }
 
posted @ 2016-03-24 16:40  清澈见底  阅读(405)  评论(0编辑  收藏  举报