Android Binder javajni源码分析
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder javajni源码分析相关的知识,希望对你有一定的参考价值。
android开发中java端调用getSystemService(xxx);
getSystemService(Context.CONNECTIVITY_SERVICE);
Activity.java 路径 frameworks/base/core/java/android/app/Activity.java
如果获取的Service不是代码中所示的,那么就调用父类ContextThemeWrapper的getSystemService
public class Activity extends ContextThemeWrapper
...
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
}
ContextThemeWrapper.java
路径 frameworks/base/core/java/android/view/ContextThemeWrapper.java
getBaseContext() 返回的实际是Context的子类,ContextImpl
@Override
public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
ContextImpl.java 路径 frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry.java
路径 frameworks/base/core/java/android/app/SystemServiceRegistry.java
这里面存在的静态代码块就是调用的ServiceManager.getServiceOrThrow获取系统binder对象的
IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
final class SystemServiceRegistry {
private static final String TAG = "SystemServiceRegistry";
......
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
private static int sServiceCacheSize;
// Not instantiable.
private SystemServiceRegistry() { }
static {
......
registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
@Override
public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
return new ConnectivityManager(context, service);
}});
......
}
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
......
}
ServiceManager.java 路径 frameworks/base/core/java/android/os/ServiceManager.java
调用本类中的getService方法
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}
ServiceManager.java 路径frameworks/base/core/java/android/os/ServiceManager.java
这里面主要是调用了getIServiceManager().getService(name)
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().getService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
getIServiceManager()
Binder.allowBlocking(BinderInternal.getContextObject()) 这块应该是返回ServiceManager的IBinder对象用来进行ServiceManager的跨进程通信
BinderInternal.getContextObject() 最终返回的就是android/os/BinderProxy对象
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
BinderInternal.getContextObject()
路径 frameworks/base/core/java/com/android/internal/os/BinderInternal.java
这是一个native方法,jni方法那就根据包名类名找到对应的jni方法
其实这里最终返回的就是android/os/BinderProxy对象
public static final native IBinder getContextObject();
android_os_BinderInternal_getContextObject
路径 frameworks/base/core/jni/android_util_Binder.cpp
javaObjectForIBinder将native层的IBinder对象转换为java层的IBinder对象
sp<IBinder> b = new BpBinder(0);
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
//相当于 sp<IBinder> b = new BpBinder(0);
return javaObjectForIBinder(env, b);
}
ProcessState::self()->getContextObject(NULL)
路径 frameworks/native/libs/binder/ProcessState.cpp
getStrongProxyForHandle Handle等于0代表获取ServiceManager
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
getStrongProxyForHandle
这里面调用了lookupHandleLocked构造了一个handle_entry,然后ping了一下ServiceManager,最后new了一个BpBinder返回
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
lookupHandleLocked
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
const size_t N=mHandleToObject.size();
if (N <= (size_t)handle) {
handle_entry e;
e.binder = NULL;
e.refs = NULL;
status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
if (err < NO_ERROR) return NULL;
}
return &mHandleToObject.editItemAt(handle);
}
回到jni的代码javaObjectForIBinder
路径 frameworks/base/core/jni/android_util_Binder.cpp
这个函数主要的作用就是将native的对象转化为java的对象,省略的部分就是函数的检查部分,接下来调用env的创建对象函数gBinderProxyOffsets.mClass android/os/BinderProxy的java字节码文件,并将上文中创建好的 sp<IBinder> b = new BpBinder(0);传递给BinderProxy的mObject对象
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
...
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
...
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
...
//这个native对象需要保留一个对代理的弱引用,这样就可以在同一个代理仍然处于活动状态时检索它。
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
...
}
return object;
}
gBinderProxyOffsets
路径 frameworks/base/core/jni/android_util_Binder.cpp
android/os/BinderProxy的java类这里面获取了关于这个类的构造器和成员变量
const char* const kBinderProxyPathName = "android/os/BinderProxy";
//结构体
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mConstructor;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mObject;
jfieldID mSelf;
jfieldID mOrgue;
} gBinderProxyOffsets;
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
以上是关于Android Binder javajni源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android Framework实战开发-binder通信java及jni部分源码分析
Android Framework实战开发-binder通信java及jni部分源码分析
Binder 机制分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )