您的位置:首页 > 编程语言 > Java开发

Binder系统_JAVA实现内部机制Server端

2018-01-14 21:29 405 查看
一、server怎么读到数据?

使用app_process来启动APP

C:\Android-5.0.2\Android-5.0.2\android-5.0.2-fs-20150325\android-5.0.2\frameworks\base\cmds\app_process

文件在这个目录下。

virtual void onStarted()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();

AndroidRuntime* ar = AndroidRuntime::getRuntime();
ar->callMain(mClassName, mClass, mArgs);

IPCThreadState::self()->stopProcess();
}
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
res = androidCreateRawThreadEtc(_threadLoop,
this, name, priority, stack, &mThread);
}


创建线程并传入参数,执行函数。
最终执行到他自己的threadLoop函数
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}joinThreadPool已经说过。是个循环

二、server读到数据后怎么调用某服务的onTransact函数?

驱动他会把cookie转化成BBinder对象(C++对象)然后调用它的tracsact函数

那么他是在哪里设置的

是在addService时设置的

service会通过JNI调用C++函数:

创建一个BBinder派生类JavaBBinder对象,它的.mObject指向java对象:new HelloService()

它含有onTransact函数

吧这个对象存入.cookie(最终存入binder驱动中该服务中对应的binder_node.cookie)

server进程从驱动读到数据里面还有.cookie转化为BBinder对象调用它的transact函数最终会调用派生类JavaBBinder的onTransact

函数。

ServiceManager.addService("hello", new HelloService());就是执行的是SMProxy的addService函数
data.writeStrongBinder(service);
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}


使用JNI
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);//将val写到cookie
}


其实对client来说是从上往下的。、
对server来说是从下往上的。

这里构造一个JavaBBinder对象(C++),它的mObject = new HelloService JAVA对象

(构造BinderProxy对象(java)它的 .mObject = new BpBinder(c++))

然后让.cookie = JavaBBinder对象(C++)

(.mRemote = BinderProxy对象(java))

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;

if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}

if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}

ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}把HelloSerice对象转化为JavaBBinderjava对象
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}

return b;
}


调用get函数
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}

构造函数
现在得到了一个JavaBBinder对象它的mObject==new HelloService对象--java的

然后作为参数传给cookie

zai javaBBinder的onTransact函数中

jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);mobject指向HelloService对象
mExecTransact指向Binder类中的execTransact方法

这句话意思就是调用HelloService对象中的execTransact方法

private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
try {
res = onTransact(code, data, reply, flags);

然后就调用到了HelloService的onTransact函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐