안 드 로 이 드 소스 3
56747 단어 android
Android 시스템 에서 자바 초창기 에 시스템 은 JNI 함 수 를 미리 등록 합 니 다.그 중에서 자바 Binder 와 Native Binder 의 상호작용 관 계 를 구축 하 는 함수 가 있 습 니 다.rameworks\base\core\jni\\androidutil_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
// Java Binder Native
if (int_register_android_os_Binder(env) < 0)
return -1;
// Java BinderInternal Native
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
// Java BinderProxy Native
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
// Java Parcel Native
if (int_register_android_os_Parcel(env) < 0)
return -1;
return 0;
}
Binder 클래스 초기 화
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz;
//kBinderPathName Java Binder ,“android/os/Binder“
clazz = env->FindClass(kBinderPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
/*
gBinderOffSets , Binder JNI ,
execTranscat methodID,Binder mObject fildID
*/
gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderOffsets.mExecTransact
= env->GetMethodID(clazz, "execTransact", "(IIII)Z");
assert(gBinderOffsets.mExecTransact);
gBinderOffsets.mObject
= env->GetFieldID(clazz, "mObject", "I");
assert(gBinderOffsets.mObject);
// Binder native
return AndroidRuntime::registerNativeMethods(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
BinderInternal 클래스 초기 화
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz;
// BinderInternal jclass 。
// “com/android/internal/os/BinderInternal”
clazz = env->FindClass(kBinderInternalPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
// forceBinderGc methodID
gBinderInternalOffsets.mForceGc
= env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
assert(gBinderInternalOffsets.mForceGc);
// BinderInternal native
return AndroidRuntime::registerNativeMethods(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
BinderProxy 클래스 초기 화
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz;
clazz = env->FindClass("java/lang/ref/WeakReference");
LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
//gWeakReferenceOffsets WeakReference
gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
// WeakReference get MethodID
gWeakReferenceOffsets.mGet
= env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
assert(gWeakReferenceOffsets.mGet);
//gErrorOffsets Error
clazz = env->FindClass("java/lang/Error");
LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
//gBinderProxyOffsets BinderProxy
gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
// BinderProxy
clazz = env->FindClass(kBinderProxyPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderProxyOffsets.mConstructor
= env->GetMethodID(clazz, "" , "()V");
assert(gBinderProxyOffsets.mConstructor);
gBinderProxyOffsets.mSendDeathNotice
= env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
assert(gBinderProxyOffsets.mSendDeathNotice);
gBinderProxyOffsets.mObject
= env->GetFieldID(clazz, "mObject", "I");
assert(gBinderProxyOffsets.mObject);
gBinderProxyOffsets.mSelf
= env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
assert(gBinderProxyOffsets.mSelf);
// BinderProxy native
return AndroidRuntime::registerNativeMethods(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
int_register_android_os_BinderProxy 함 수 는 BinderProxy 클래스 를 초기 화 하 는 것 외 에 WeakReference 클래스 와 Error 클래스 의 일부 정 보 를 얻 었 습 니 다.
하나의 예 를 통 해 자바 Binder 의 작업 절 차 를 분석 하고 먼저 AMS 가 자신 을 ServiceManager 에 어떻게 등록 하 는 지 분석 한 다음 에 AMS 가 클 라 이언 트 의 Binder 호출 요청 에 어떻게 응답 하 는 지 분석 합 니 다.frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
// ActivityManagerService ServiceManager
ServiceManager.addService("activity", m);
ServiceManager.addService("meminfo", new MemBinder(m));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
ServiceManager.addService("activity.services", new ServicesBinder(m));
ServiceManager.addService("activity.senders", new SendersBinder(m));
ServiceManager.addService("activity.providers", new ProvidersBinder(m));
ServiceManager.addService("permission", new PermissionController(m));
ApplicationInfo info =
mSelf.mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
synchronized (mSelf) {
ProcessRecord app = mSelf.newProcessRecordLocked(
mSystemThread.getApplicationThread(), info,
info.processName);
app.persistent = true;
app.pid = Process.myPid();
app.maxAdj = SYSTEM_ADJ;
mSelf.mProcessNames.put(app.processName, app.info.uid, app);
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
mSelf.updateLRUListLocked(app, true);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
위 에서 보 여 준 코드 줄 의 목적 은 Activity Manager 서비스 서 비 스 를 ServiceManager 에 추가 하여 어떻게 등록 하 는 것 입 니까?
서비스 frameworks\base\core\java\android\os\\ServiceManager.java 를 ServiceManager 에 등록 합 니 다.
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService(String name, IBinder service) {
try {
//getIServiceManager
getIServiceManager().addService(name, service);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
// asInterface, IBinder
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
asInterface 의 인 자 는 BinderInternal.getContextObject 의 반환 값 입 니 다.이것 은 native 함수 입 니 다.그 실현 코드 는 frameworks\base\core\jni\android 입 니 다.util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
// Native Java ,
return javaObjectForIBinder(env, b);
}
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
//printf("objectForBinder %p: it's our own %p!
", val.get(), object);
return object;
}
// For the rest of the function we will hold this lock, to serialize
// looking/creation of Java proxies for native Binder proxies.
//mProxyLock CMutex
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
/*
val BpBinder, BpBinder.cpp findObject 。
, Native BpBinder ObjectManager, Native BpBinder
Java BpBinder 。 findObject gBinderProxyOffsets
ObjectManager 。 , object
*/
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
if (res != NULL) {
LOGV("objectForBinder %p: found existing %p!
", val.get(), res);
return res;
}
LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
// BinderProxy , Native BpBinder ObjectManager
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGV("objectForBinder %p: created new %p!
", val.get(), object);
// The proxy holds a reference to the native object.
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
val->incStrong(object);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
/*
BinderProxy (attach) BpBinder ObjectManager ,
proxy_cleanup。 BinderProxy (detach) ,
, 。 proxy_cleanup 。
*/
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Note that a new object reference has been created.
// Proxy
android_atomic_inc(&gNumProxyRefs);
// 。 Proxy 200 ,
// BinderInter ForceGc
incRefsCreated(env);
}
return object;
}
ServiceManager Native 클래스 의 asInterface 함수 frameworks\base\\core\\java\android\os\\ServiceManager Native.java 분석
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
// obj , ServiceManagerProxy
return new ServiceManagerProxy(obj);
}
addService 함수 분석 분석 ServiceManager Proxy 의 addService 함수
public void addService(String name, IBinder service)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
// writeStrongBinder ,
data.writeStrongBinder(service);
//mRemote BinderProxy , transact,
//
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
BinderProxy 의 transact 는 native 함수 로 함 수 를 실현 하 는 코드 는 다음 과 같 습 니 다 frameworks\base\core\jni\androidutil_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj,
jobject replyObj, jint flags)
{
if (dataObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return JNI_FALSE;
}
// Java Parcel Native Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
// Parcel
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
// Java BinderProxy Native BpBinder
IBinder* target = (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
LOGV("Java code calling transact on %p in Java object %p with code %d
",
target, obj, code);
//printf("Transact from Java code to %p sending: ", target); data->print();
// Native BpBinder , ServiceManager
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err);
return JNI_FALSE;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.