启动一个新的应用程序时,首先会调用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);28042805        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    }
                                  

更多相关文章

  1. Android(安卓)Context 是什么?
  2. Android中第五大组件详解
  3. Android用SharedPreferences记住用户名
  4. Android开发之拖动条/滑动条控件、星级评分控件功能的实例代码
  5. Android进程启动流程(App启动)
  6. Android之单元测试
  7. Android开发---为按钮添加事件的三种方法
  8. AndroidStudio 报 Error:Execution failed for task ':app:proce
  9. Android之设置EditText输入类型(setInputType()方法和android:in

随机推荐

  1. sqlserver中delete、update中使用表别名
  2. Sql学习第三天——SQL 关于CTE(公用表达
  3. Sql学习第三天——SQL 关于with ties介绍
  4. Sql学习第二天——SQL DML与CTE概述
  5. Sql学习第一天——SQL 将变量定义为Table
  6. Sql学习第一天——SQL 练习题(建表/sql语
  7. Sql学习第一天——SQL UNION 和 UNION AL
  8. sqlserver附加.mdf权限问题解决
  9. SQL普通表转分区表的方法
  10. 游标删除多个表里脏数据的方法