注册

分享Android App的几个核心概念

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中的布局。

作者:沐小琪吖
链接:https://juejin.cn/post/7249186287578660922
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册