android java服务,Android进阶学习必会:Java Binder中的系统服务
前言
這個(gè)知識(shí)點(diǎn)是Android進(jìn)階學(xué)習(xí)必須掌握的知識(shí)點(diǎn)之一,也是高階Android架構(gòu)師經(jīng)常問到的點(diǎn)。在這里分想給大家,希望對(duì)大家的工作和學(xué)習(xí)有所幫助。喜歡本文的記得點(diǎn)贊關(guān)注哦~
在前面的Android Binder原理(三)系統(tǒng)服務(wù)的注冊(cè)過程這篇文章中,我介紹的是Native Binder中的系統(tǒng)服務(wù)的注冊(cè)過程,這一過程的核心是ServiceManager,而在Java Binder中,也有一個(gè)ServiceManager,只不過這個(gè)ServiceManager是Java文件。
既然要將系統(tǒng)服務(wù)注冊(cè)到ServiceManager,那么需要選擇一個(gè)系統(tǒng)服務(wù)為例,這里以常見的AMS為例。
1.將AMS注冊(cè)到ServiceManager
在AMS的setSystemProcess方法中,會(huì)調(diào)用ServiceManager的addService方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1
....
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
...
}
注釋1處的Context.ACTIVITY_SERVICE的值為"activity",作用就是將AMS注冊(cè)到ServiceManager中。接著來看
ServiceManager的addService方法。
frameworks/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
主要分析getIServiceManager方法返回的是什么,代碼如下所示。
frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
講到這里,已經(jīng)積累了幾個(gè)點(diǎn)需要分析,分別是:
BinderInternal.getContextObject()
ServiceManagerNative.asInterface()
getIServiceManager().addService()
現(xiàn)在我們來各個(gè)擊破它們。
1.1 BinderInternal.getContextObject()
Binder.allowBlocking的作用是將BinderProxy的sWarnOnBlocking值置為false。主要來分析BinderInternal.getContextObject()做了什么,這個(gè)方法是一個(gè)Native方法,找到它對(duì)應(yīng)的函數(shù):
frameworks/base/core/jni/android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
...
};
對(duì)應(yīng)的函數(shù)為android_os_BinderInternal_getContextObject:
frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);//1
return javaObjectForIBinder(env, b);
}
ProcessState::self()的作用是創(chuàng)建ProcessState,注釋1處最終返回的是BpBinder,不理解的可以查看Android Binder原理(二)ServiceManager中的Binder機(jī)制這篇文章。
BpBinder是Native Binder中的Client端,這說明Java層的ServiceManager需要Native層的BpBinder,但是這個(gè)BpBinder在Java層是無法直接使用,那么就需要傳入javaObjectForIBinder函數(shù)來做處理,其內(nèi)部會(huì)創(chuàng)建一個(gè)BinderProxy對(duì)象,這樣我們得知 BinderInternal.getContextObject()最終得到的是BinderProxy。
在Android Binder原理(六)Java Binder的初始化這篇文章我們講過,BinderProxy是Java Binder的客戶端的代表。
需要注意的一點(diǎn)是,這個(gè)傳入的BpBinder會(huì)保存到BinderProxy的成員變量mObject中,后續(xù)會(huì)再次提到這個(gè)點(diǎn)。
1.2 ServiceManagerNative.asInterface()
說到asInterface方法,在Native Binder中也有一個(gè)asInterface函數(shù)。在Android Binder原理(二)ServiceManager中的Binder機(jī)制這篇文章中講過IServiceManager的asInterface函數(shù),它的作用是用BpBinder做為參數(shù)創(chuàng)建BpServiceManager。那么在Java Binder中的asInterface方法的作用又是什么?
frameworks/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
根據(jù)1.1小節(jié),我們得知obj的值為BinderProxy,那么asInterface方法的作用就是用BinderProxy作為參數(shù)創(chuàng)建ServiceManagerProxy。
BinderProxy和BpBinder分別在Jave Binder和Native Binder作為客戶端的代表,BpServiceManager通過BpBinder來實(shí)現(xiàn)通信,同樣的,ServiceManagerProxy也會(huì)將業(yè)務(wù)的請(qǐng)求交給BinderProxy來處理。
分析到這里,那么:
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
可以理解為:
sServiceManager = new ServiceManagerProxy(BinderProxy);
}
1.3 getIServiceManager().addService()
根據(jù)1.2節(jié)的講解,getIServiceManager()返回的是ServiceManagerProxy,ServiceManagerProxy是ServiceManagerNative的內(nèi)部類,它實(shí)現(xiàn)了IServiceManager接口。
來查看ServiceManagerProxy的addService方法,
frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);//1
data.writeInt(allowIsolated ? 1 : 0);
data.writeInt(dumpPriority);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2
reply.recycle();
data.recycle();
}
注釋1處的data.writeStrongBinder很關(guān)鍵,后續(xù)會(huì)進(jìn)行分析。這里又看到了Parcel,它是一個(gè)數(shù)據(jù)包裝器,將請(qǐng)求數(shù)據(jù)寫入到Parcel類型的對(duì)象data中,通過注釋1處的mRemote.transact發(fā)送出去,mRemote實(shí)際上是BinderProxy,BinderProxy.transact是native函數(shù),實(shí)現(xiàn)的函數(shù)如下所示。
frameworks/base/core/jni/android_util_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
if (dataObj == NULL) {
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
}
Parcel* data = parcelForJavaObject(env, dataObj);//1
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);//2
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
IBinder* target = getBPNativeData(env, obj)->mObject.get();//3
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
...
status_t err = target->transact(code, *data, reply, flags);//4
return JNI_FALSE;
}
注釋1和注釋2處,將Java層的Parcel對(duì)象轉(zhuǎn)化成為Native層的Parcel對(duì)象。在1.1小節(jié)中,我們得知BpBinder會(huì)保存到BinderProxy的成員變量mObject中,因此在注釋3處,從BinderProxy的成員變量mObject中獲取BpBinder。最終會(huì)在注釋4處調(diào)用BpBinder的transact函數(shù),向Binder驅(qū)動(dòng)發(fā)送數(shù)據(jù),可以看出Java Binder是需要Native Binder支持的,最終的目的就是向Binder驅(qū)動(dòng)發(fā)送和接收數(shù)據(jù)。
2.引出JavaBBinder
接著回過頭來分析1.3小節(jié)遺留下來的data.writeStrongBinder(service),代碼如下所示。
frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder ll) {
nativeWriteStrongBinder(mNativePtr, val);
}
nativeWriteStrongBinder是Native方法,實(shí)現(xiàn)的函數(shù)為android_os_Parcel_writeStrongBinder:
frameworks/base/core/jni/android_os_Parcel.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));//1
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
接著查看注釋1處ibinderForJavaObject函數(shù):
frameworks/base/core/jni/android_util_Binder.cpp
sp ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//1
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get(env, obj);//2
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
注釋2處,如果obj是Java層的BinderProxy類,則返回BpBinder。
注釋1處,如果obj是Java層的Binder類,那么先獲取JavaBBinderHolder對(duì)象,然后在注釋2處調(diào)用JavaBBinderHolder的get函數(shù),代碼如下所示。
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder
class JavaBBinderHolder
{
public:
sp get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp b = mBinder.promote();//1
if (b == NULL) {
//obj是一個(gè)Java層Binder對(duì)象
b = new JavaBBinder(env, obj);//2
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp mBinder;
};
成員變量mBinder是wp類型的弱引用,在注釋1處得到sp類型的強(qiáng)引用b,在注釋2處創(chuàng)建JavaBBinder并賦值給b。那么,JavaBBinderHolder的get函數(shù)返回的是JavaBBinder。
data.writeStrongBinder(service)在本文中等價(jià)于:
data.writeStrongBinder(new JavaBBinder(env,Binder))。
講到這里可以得知ServiceManager.addService()傳入的并不是AMS本身,而是JavaBBinder。
3.解析JavaBBinder
接著來分析JavaBBinder,查看它的構(gòu)造函數(shù):
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
gcIfManyNewRefs(env);
}
...
可以發(fā)現(xiàn)JavaBBinder繼承了BBinder,那么JavaBBinder的作用是什么呢?當(dāng)Binder驅(qū)動(dòng)得到客戶端的請(qǐng)求,緊接著會(huì)將響應(yīng)發(fā)送給JavaBBinder,這時(shí)會(huì)調(diào)用JavaBBinder的onTransact函數(shù),代碼如下所示。
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast(&data), reinterpret_cast(reply), flags);//1
...
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
在注釋1處會(huì)調(diào)用Java層Binder的execTransact函數(shù):
frameworks/base/core/java/android/os/Binder.java
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
...
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
res = onTransact(code, data, reply, flags);//1
} catch (RemoteException|RuntimeException e) {
...
}
...
return res;
}
關(guān)鍵點(diǎn)是注釋1處的onTransact函數(shù),AMS實(shí)現(xiàn)了onTransact函數(shù),從而完成業(yè)務(wù)實(shí)現(xiàn)。
從這里可有看出,JavaBBinder并沒有實(shí)現(xiàn)什么業(yè)務(wù),當(dāng)它接收到請(qǐng)求時(shí),會(huì)調(diào)用Binder類的execTransact函數(shù),execTransact函數(shù)內(nèi)部又調(diào)用了onTransact函數(shù),系統(tǒng)服務(wù)會(huì)重寫onTransact函數(shù)來實(shí)現(xiàn)自身的業(yè)務(wù)功能。
4.Java Binder架構(gòu)
Binder架構(gòu)如下圖所示。
Native Binder的部分在此前的文章已經(jīng)講過,這里主要來說說Java Binder部分,從圖中可以看到:
1.Binder是服務(wù)端的代表,JavaBBinder繼承BBinder,JavaBBinder通過mObject變量指向Binder。
2.BinderProxy是客戶端的代表,ServiceManager的addService等方法會(huì)交由ServiceManagerProxy處理。
3.ServiceManagerProxy的成員變量mRemote指向BinderProxy對(duì)象,所以ServiceManagerProxy的addService等方法會(huì)交由BinderProxy來處理。
4.BinderProxy的成員變量mObject指向BpBinder對(duì)象,因此BinderProxy可以通過BpBinder和Binder驅(qū)動(dòng)發(fā)送數(shù)據(jù)。
最后
千里之行始于足下 。
Android學(xué)習(xí)是一條漫長的道路,我們要學(xué)習(xí)的東西不僅僅只有表面的 技術(shù),還要深入底層,弄明白下面的 原理,只有這樣,我們才能夠提高自己的競爭力,在當(dāng)今這個(gè)競爭激烈的世界里立足。
我把自己這段時(shí)間整理的Android最重要最熱門的學(xué)習(xí)方向資料放在了我的GitHub:https://github.com/xieyuliang/Android-P7-(點(diǎn)擊藍(lán)色字體可以獲取),里面還有不同方向的自學(xué)編程路線、面試題集合/面經(jīng)、及系列技術(shù)文章等。
資源持續(xù)更新中,歡迎大家一起學(xué)習(xí)和探討。
部分資料截圖展示:
總結(jié)
以上是生活随笔為你收集整理的android java服务,Android进阶学习必会:Java Binder中的系统服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: u盘不能显示了怎么办啊 U盘失灵了怎么办
- 下一篇: android自动更新列表,Androi