- 浏览: 53199 次
- 性别:
- 来自: 武汉
最新评论
-
Stark_Summer:
很好 顶顶
android 面试题经典 -
fff32165:
LZ好牛啊!膜拜ing
activity与service的交互
ActivityManager在操作系统中有重要的作用,本文利用操作系统源码,逐步理清ActivityManager的框架,并从静态类结构图和动态序列图两个角度分别进行剖析,从而帮助开发人员加强对系统框架及进程通信机制的理解。
ActivityManager的作用
参照SDK的说明,可见ActivityManager的功能是与系统中所有运行着的Activity交互提供了接口,主要的接口围绕着运行中的进程信息,任务信息,服务信息等。比如函数getRunningServices()的源码是:
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
从中可以看到,ActivityManager的大多数功能都是调用了ActivityManagerNative类接口来完成的,因此,我们寻迹来看ActivityManagerNative的代码,并以此揭示ActivityManager的整体框架。
ActivityManager的静态类图
通过源吗,可以发现ActivityManagerNative类的继承关系如下:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
继承自Binder类,同时实现了IActivityManager接口。
同样的,我们继续沿Binder和IActivityManager上溯,整理出如下图所示的类结构图。
在这张图中,绿色的部分是在SDK中开放给应用程序开发人员的接口,蓝色的部分是一个典型的Proxy模式,红色的部分是底层的服务实现,是真正的动作执行者。这里的一个核心思想是Proxy模式,我们接下来对此模式加以介绍。
Proxy模式
Proxy模式,也称代理模式,是经典设计模式中的一种结构型模式,其定义是为其他对象提供一种代理以控制对这个对象的访问,简单的说就是在访问和被访问对象中间加上的一个间接层,以隔离访问者和被访问者的实现细节。
结合上面的类结构图,其中ActivityManager是一个客户端,为了隔离它与ActivityManagerService,有效降低甚至消除二者的耦合度,在这中间使用了ActivityManagerProxy代理类,所有对ActivityManagerService的访问都转换成对代理类的访问,这样ActivityManager就与ActivityManagerService解耦了。这就是代理模式的典型应用场景。
为了让代理类与被代理类保持一致的接口,从而实现更加灵活的类结构,或者说完美的屏蔽实现细节,通常的作法是让代理类与被代理类实现一个公共的接口,这样对调用者来说,无法知道被调用的是代理类还是直接是被代理类,因为二者的接口是相同的。
这个思路在上面的类结构图里也有落实,IActivityManager接口类就是起的这个作用。
以上就是代理模式的思路,有时我们也称代理类为本地代理(Local Proxy),被代理类为远端代理(Remote Proxy)。
本地代理与远端代理的Binder
我们再来看一下Binder类的作用,Binder的含义可能译为粘合剂更为贴切,即将两侧的东西粘贴起来。在操作系统中,Binder的一大作用就是连接本地代理和远端代理。Binder中最重要的一个函数是:
public final boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
……
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
它的作用就在于通过code来表示请求的命令标识,通过data和reply进行数据传递,只要远端代理能实现onTransact()函数,即可做出正确的动作,远端的执行接口被完全屏蔽了。
当然,Binder的实现还是很复杂的,不仅是类型转换,还要透过Binder驱动进入KERNEL层来完成进程通信,这些内容不在本文的范围之内,故此处不再深入解析相应的机制。此处我们只要知道Binder的transact()函数实现就可以了。
到此为止,我们对ActivityManager的静态类结构就分析完了,但这还不足以搞清在系统运行中的调用过程,因此,我们以下图的序列图为基础,结合源码探索一下ActivityManager运行时的机制。
动态序列图
我们以ActivityManager的getRunningServices()函数为例,对上述序列图进行解析。
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
可以看到,调用被委托到了ActivatyManagerNative.getDefault()。
static public IActivityManager asInterface(IBinder obj)
{
……
return new ActivityManagerProxy(obj);
}
static public IActivityManager getDefault()
{
……
IBinder b = ServiceManager.getService("activity");
gDefault = asInterface(b);
return gDefault;
}
从上述简化后的源码可以看到,getDefault()函数返回的是一个ActivityManagerProxy对象的引用,也就是说,ActivityManager得到了一个本地代理。
因为在IActivityManager接口中已经定义了getServices()函数,所以我们来看这个本地代理对该函数的实现。
public List getServices(int maxNum, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
……
mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
……
}
从这个代码版段我们看到,调用远端代理的transact()函数,而这个mRemote就是ActivityManagerNative的Binder接口。
接下来我们看一下ActivityManagerNative的代码,因为该类是继承于Binder类的,所以transact的机制此前我们已经展示了代码,对于该类而言,重要的是对onTransact()函数的实现。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case GET_SERVICES_TRANSACTION: {
……
List list = getServices(maxNum, fl);
……
return true;
}
……
}
return super.onTransact(code, data, reply, flags);
}
在onTrasact()函数内,虽然代码特别多,但就是一个switch语句,根据不同的code命令进行不同的处理,比如对于GET_SERVICES_TRANSACTION命令,只是调用了getServices()函数。而该函数的实现是在ActivityManagerService类中,它是ActivityManagerNative的子类,对于该函数的实现细节,不在本文中详细分析。
Activity启动
在经过前文的学习以后,我们一起来整理一下Activity的启动机制。就从Activity的startActivity()函数开始吧。
startActivity()函数调用了startActivityForResult()函数,该函数有源码如下:
public void startActivityForResult(Intent intent, int requestCode) {
……
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
……
}
可见,功能被委托给Instrumentation对象来执行了。这个类的功能是辅助Activity的监控和测试,在此我们不详细描述,我们来看它的execStartActivity()函数。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
……
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
在这个函数里,我们看到了前文熟悉的ActivityManagerNative.getDefault(),没错,利用了ActivityManagerService。通过前文的线索,利用Proxy模式,我们可以透过ActivityManagerProxy,通过Binder的transact机制,找到真正的动作执行者,即ActivityManagerService类的startActivity()函数,并沿此线索继续追踪源码,在startActivityLocked()函数里边看到了mWindowManager.setAppStartingWindow的语句调用,mWindowManager是WindowManagerService对象,用于负责界面上的具体窗口调试。
通过这样的源码追踪,我们了解到了Activity启动的底层实现机制,也加深了对Proxy模式和Binder机制的理解。从而为学习其他框架打下了基础。
总结
本文从静态类结构和动态类结构两个角度分析了ActivityManager的框架,兼顾了Binder机制和代理模式在进程间通信的机理,对帮助开发人员深化操作系统的结构和框架具有一定的指导作用。
转载自:http://www.apkbus.com/forum.php?mod=viewthread&tid=1155&extra
发表评论
-
hydra框架中js与java互调原理
2019-06-10 17:18 0本文档主要阐述hydra框架中js与java是如何实现相互 ... -
自定义gradle插件
2019-09-02 11:25 3491.Gradle插件 Gradle可以认为是一个框 ... -
Rxjava2使用
2019-04-24 17:46 0Rxjava是一个基于观察者模式,通过可观察对象发送数据流 ... -
android NDK cmake
2019-04-19 16:00 0CMake是一个跨平台的安 ... -
504 Unsatisfiable Request 问题解决
2019-04-15 11:09 0问题出现背景及描述:在业务中使用Retrofit2网络工具库进 ... -
adb 命令操作
2019-04-11 16:46 0解决ANR还得需要trace.txt ... -
Android Framework之常用类介绍
2012-05-17 09:10 0WindowManagerService 窗口调度服务 ... -
application私有文件访问
2012-05-16 23:13 0首先内部存储路径为/data/data/youPackageN ... -
BroadcastReceiver的使用
2011-12-15 09:47 780使用广播接收器有两种方法,一种是建立一个BroadcastRe ... -
android:gravity 与 layout_gravity的区别
2011-10-27 16:04 655android:gravity 本view内部信息的排列方式对 ... -
activity与service的交互
2011-07-31 13:16 1523Activity访问service有两种方式,第一种是通过Ib ... -
android用于打开各种文件的intent
2011-07-29 23:33 977android用于打开各种文件的intent 2011-03 ... -
Android Application Task Activities的关系
2011-07-05 22:11 774什么是Android Application ... -
Android的PackageManager和ActivityManager的功能简介
2011-07-05 21:56 939Android系统为应用管理功能提供了大量的API。根据功能的 ... -
Android 对话框(Dialog)大全
2011-06-30 20:38 713Android 对话框(Dialog)大全 建立你自己的对 ... -
android 开发环境搭建
2011-06-19 15:15 7001.jdk安装及环境变量配置 以jdk1.4 ... -
[Android]正确地访问网络资源----Proxy的使用
2011-05-27 15:15 2453天朝有很多独特的东西,今天要涉及到的是CMWAP与CMNET。 ... -
指定浏览器访问指定页面(支持UC、Opera、QQ、Dolphin、Skyfire、Steel、Google)
2011-05-27 14:32 1278/*先看一下系统浏览器com.android.browser ... -
android:webView总结
2011-05-27 10:02 1083在Android手机中内置了一款高性能webkit内核浏览器, ... -
android 发送短信
2011-05-25 17:56 743要使用手机短信服务,在AndroidManifest.xml中 ...
相关推荐
ActivityManager框架解析归纳.pdf
NULL 博文链接:https://newbin.iteye.com/blog/552144
就也是同一个应用会有两个PID,结果在控制台查看打印的LOG,不同方式启动的LOG如下: 代码如下:09-22 09:39:11.929: INFO/ActivityManager(61): Starting: Intent { act=android.intent.action.MAIN cat=[android....
Android ActivityManager系统文档分析总结,详细介绍了ActivityManager的各种模式
源码基于 Android 10 此图着重提炼了生命周期的部分,Android 10 中 新增了 ActivityTaskManager ,专门用于管理 Activity,接替了 ActivityManager 的一部分工作 理解 Instrumentation Activity 首先会通过 ...
Activity_Manager框架解析
作者tiann,源码understand-plugin-framework,分析DroidPlugin,深入理解插件化框架,内容如下: Hook机制之动态代理 Hook机制之Binder Hook Hook机制之AMS&PMS Activity生命周期管理,占坑和Hook 广播的处理方式 ...
活动管理器android活动管理器
ActivityManager学习。了解activity运行原理
Android中获取正在运行的应用程序-----ActivityManager的使用(二) Android中获取正在运行的应用程序-----ActivityManager的使用(二)
Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager,etc)和相应ManagerService的桥梁 从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当你bindService的时候,服务端会返回一...
本文实例讲述了Android开发之开门狗在程序锁中的应用方法。分享给大家供大家参考,具体如下: protected static final String TAG = WatchDogService; private AppLockDao dao; private List<String> lockApps; ...
轻松开发Android的基础框架。 德斯 该框架封装了基本功能,例如我们使用okhttp的网络框架,Android 6.0的运行权限检查,ORM,从相机或图库或文件系统拍照等。 特征 封装OkHttp。 (包括加载拦截器) 定制的Gson,...
Android上简单实现四大组件的插件化说明:此项目仅用于学习插件化基本的实现思路,在此基础上学习理解四大组件的运行机制。实现插件化的重点在于对Android四大组件和资源加载流程的分析和解读。插件化代码的编写,...
Android ActivityManager API 对比总结,详细介绍了对比情况