分享Android App的几个核心概念

ea6387ef0345515755e13bb711bb3543--809802570.jpg
我正在参加「·启航计划」

Application发动

点击桌面图标发动App(如下流程图)

1240.jpg

针对以上流程图示:

  • ActivityManagerService#startProcessLocked()
  • Process#start()
  • ActivityThread#main(),入口分析的地方
  • ActivityThread#attach(),这个里边的逻辑很中心 ActivityManagerService#attachApplication(),经过Binder机制调用了ActivityManagerService的attachApplication
  • ActivityManagerService#attachApplicationLocked(),整个使用进程现已发动起来
  • ActivityManagerService#thread.bindApplication,详细回到ActivityThread
  • ActivityThread.ApplicationThread#bindApplication(),最终看到sendMessage处理bind逻辑
  • ActivityThread#handleBindApplication(),设置进程的pid,初始化进程信息
  • ActivityThread#mInstrumentation.callApplicationOnCreate,看到Application进入onCreate()办法中,这便是从最开端main()办法开端到最终的Application的onCreate()的创立进程

Window创立

如何创立Window

在创立Activity实例的同时,会调用Activity的内部办法attach办法完成window的初始化。Activity类中相关源码如下所示:

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback) {
    //创立 PhoneWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
}
  • Window是一个抽象类,详细实现是PhoneWindow。PhoneWindow中有个内部类DecorView,经过创立DecorView来加载Activity中设置的布局R.layout.activity_main
  • 创立Window需要经过WindowManager创立,经过WindowManager将DecorView加载其中,并将DecorView交给ViewRoot,进行视图绘制以及其他交互

Android组件规划

ActivityManagerService

  • 发动组件

    • 组件发动时,检查其所要运转在的进程是否已创立。如果现已创立,就直接告诉它加载组件。否则,先将该进程创立起来,再告诉它加载组件。
  • 封闭组件

    • 组件封闭时,其所运转在的进程无需封闭,这样就可以让组件重新翻开时得到快速发动。
  • 保护组件状态

    • 保护组件在运转进程的状态,这样组件就可以在其所运转在的进程被收回的情况下依然继续生存。
  • 进程管理

    • 在适当的时候主动收回空进程和后台进程,以及告诉进程自己进行内存收回

    • 组件的UID和Process Name仅有决议了其所要运转在的进程。

    • 每次组件onStop时,都会将自己的状态传递给AMS保护。

    • AMS在以下四种情况下会调用trimApplications来主动收回进程:

      • A.activityStopped,中止Activity
      • B.setProcessLimit,设置进程数量限制
      • C.unregisterReceiver,注销Broadcast Receiver
      • D.finishReceiver,结束Broadcast Receiver

Binder

  • 为组件间通讯供给支撑

    • 进程间;进程内都可以
  • 高效的IPC机制

    • 进程间的组件通讯时,通讯数据只需一次复制
    • 进程内的组件通讯时,跳过IPC进行直接的通讯

说一说DecorView

DecorView是什么

  • DecorView是FrameLayout的子类,它是Android视图树的根节点视图

    • DecorView作为顶级View,一般情况下内部包括一个竖直方向的LinearLayout,在这个LinearLayout里边有上下三个部分,上面是个ViewStub,延迟加载的视图(设置ActionBar,依据Theme设置),中心的是标题栏(依据Theme设置,有的布局没有),下面的是内容栏。
    <LinearLayout >
        <ViewStub
            android:id="@+id/action_mode_bar_stub"/>
        <FrameLayout>
            <TextView
                android:id="@android:id/title"/>
        </FrameLayout>
        <FrameLayout
            android:id="@android:id/content"/>
    </LinearLayout>
    
  • 上面的id为content的FrameLayout中,在代码中可以经过content来得到对应加载的布局

    ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
    ViewGroup rootView = (ViewGroup) content.getChildAt(0);
    

Activity 与 PhoneWindow 与 DecorView 联系

12401.jpg

一个 Activity 对应一个 PhoneWindow,一个 PhoneWindow 持有一个 DecorView 实例,DecorView 自身是一个 FrameLayout。

如何创立DecorView

  • 从Activity中的setContentView()开端

    • 在Activity中的attach()办法中,生成了PhoneWindow实例。既已有Window目标,那么就可以设置DecorView给Window目标了。
    • 从中获取mContentParent。获得到后,经过installDecor办法生成DecorView,源码中操作比较复杂,大约先从主题中获取样式,依据样式加载对应的布局到DecorView中,为mContentParent增加View,即Activity中的布局。