一、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 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 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);
}
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));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
status_t Parcel::writeStrongBinder(const sp& val)
{
return flatten_binder(ProcessState::self(), val, this);//将val写到cookie
}
对server来说是从下往上的。
这里构造一个JavaBBinder对象(C++),它的mObject = new HelloService JAVA对象
(构造BinderProxy对象(java)它的 .mObject = new BpBinder(c++))
然后让.cookie = JavaBBinder对象(C++)
(.mRemote = BinderProxy对象(java))
sp 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 get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp 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;
}
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(&data), reinterpret_cast(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);