Activity工作机制

来源:互联网 发布:小学生大数据分析 编辑:程序博客网 时间:2024/06/01 10:51
四大组件工作机制
一、Activity
1.启动类
ActivityThread:App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。
               与ActivityManagerServices配合,一起完成Activity的管理工作
ApplicationThread:是ActivityThread的内部类
                 在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。


ActivityManagerNative.getDefault()的startActivity方法启动,实际是AMSAMS的startActivity方法
ActivityManagerService(AMS)
ActivityManagerNative extends Binder implements IActivityManager
Binder-----ActivityManagerNative(继承Binder,实现IActivityManager这个binder接口)---ActivityManagerService(继承)
ActivityManagerNative.getDefault()是一个IActivityManager的Binder对象,具体实现是AMS,返回的就是ActivityManagerService的远程接口,即ActivityManagerProxy
AMS这个Binder对象采用单例模式对外提供


AMS的startActivity方法----ActivityStackSupervisor的startActivityMayWait方法------ActivityStackSupervisor的startActivityLocked方法----ActivityStackSupervisor的startActivityUncheckedLocked方法----ActivityStack的resumeTopActivitiesLocked方法
-------ActivityStack的resumeTopActivityInnnerLocked-------ActivityStackSupervisor的startSpecificActivityLocked-----ActivityStackSupervisor的realStartActivityLocked
-------realStartActivityLocked方法中app.thread.scheduleLaunchActivity()
AMS------ActivityStackSupervisor------ActivityStack


app.thread为IApplicationThread(Binder接口),IApplicationThread接口的实现者ApplicationThread完成了大量Activity及Service的启动停止操作
ApplicationThreadProxy AIDL文件自动生成的代理类




最终:ApplicationThread.scheduleLaunchActivity()方法启动Activity
方法实现:scheduleLaunchActivity()方法内部:
          发送一个启动Activity的消息交由Handler H处理,sendMessage()处理switch..case..语句
          启动过程由handleLaunchActivity()实现----performLaunchActivity()创建和启动Activity
 handleResumeActivity调onResume()
 
2.performLaunchActivity()完成的几件事:
(1)从ActivityClientRecord中获取待启动的Activity组件信息
  ActivityInfo
  component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);包名,mainActivity
(2)通过Instrumentation的newActivity方法使用类加载器创建Activity对象
   对于每一个android app来说,它的总入口都是ActivityThread::main. 每一个应用的进程都有一个ActivityThread对象,而每一个ActivityThread对象都有一个Instrumentation mInstrumentation;成员变量。mInstrumentation的初始化在ActivityThread::handleBindApplication函数中
 (3)通过loadApk的makeApplication方法来尝试创建Application对象
    创建过不会再创建,只有一个Application对象(创建通过Instrumentation完成)
Instrumentation.callApplicationOnCreate()调用Application的oncreate
(4)创建ContextImpl对象并通过Activity的attach方法完成重要数据的初始化
    ContextImpl是Context的具体实现
attach建立ContextImpl和Activity联系,完成window的创建并建立自己和window的关联,将输入事件传给Activity
 (5)调用Activity的onCreate()
   Instrumentation.callActivityOnCreate
   
3.App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程,他们之间如何通信呢?
SystemServer也是一个进程,而且是由zygote进程fork出来的,SystemServer提供多个服务,包括AMS
AMS(SystemServer进程)与zygote通过Socket进行IPC通信
AMS相当于服务端进程,App与AMS通过Binder进行IPC通信
 
AMS负责系统中所有Activity的生命周期
ActivityThread:主线程或UI线程
Instrumentation:每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象
                当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()

AMS----(Binder通信)----ActivityThread--------Instrumentation


4.底层Binder机制
Binder本质上只是一种底层通信方式,和具体服务没有关系。
为了提供具体服务,Server必须提供一套接口函数以便Client通过远程访问使用各种服务。
这时通常采用Proxy设计模式:
将接口函数定义在一个抽象类中,Server和Client都会以该抽象类为基类实现所有接口函数,所不同的是Server端是真正的功能实现,而Client端是对这些函数远程调用请求的包装。
以ActivityManagerServices和他在客户端的代理类ActivityManagerProxy为例。
ActivityManagerServices和ActivityManagerProxy都实现了同一个接口——IActivityManager


ActivityThread请求AMS,启动Activity
客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器
(都实现了相同的接口IActivityManager)


AMS想要通知ActivityThread做一些事情
客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器
(都实现了相同的接口IApplicationThread)


通过单例模式获取一个接口IActivityManager对象,这个对象通过asInterface(b)获得
Binder只能传递数据,并不知道是要调用哪个方法,所以在数据中会添加方法的唯一标识码,利用Binder对象,调用transact()
binder的唯一标识,一般用当前binder的类名表示


asInterface():同一进程,返回服务端对象本身,不同进程,返回Stub.proxy对象
asBinder:返回当前Binder对象
onTransact:运行在服务端Binder线程池中,发起请求时,远程请求会交由此方法处理,获取请求内容及参数等,执行目标方法,reply返回值






Activity启动模式使用场景:
singleTop适合接收通知启动的内容显示页面。 
例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。
singleTask适合作为程序入口点。 
例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance应用场景: 
闹铃的响铃界面。 你以前设置了一个闹铃:上午6点。在上午5点58分,你启动了闹铃设置界面,并按 Home 键回桌面;
在上午5点59分时,你在微信和朋友聊天;在6点时,闹铃响了,并且弹出了一个对话框形式的 Activity(名为 AlarmAlertActivity) 
提示你到6点了(这个 Activity 就是以 SingleInstance 加载模式打开的),你按返回键,回到的是微信的聊天界面,
这是因为 AlarmAlertActivity 所在的 Task 的栈只有他一个元素, 因此退出之后这个 Task 的栈空了。
如果是以 SingleTask 打开 AlarmAlertActivity,那么当闹铃响了的时候,按返回键应该进入闹铃设置界面。
















 
 
 
 
原创粉丝点击