Java服務一般運行在Android系統進程System
或者Android應用程序
進程中,在啟動前同樣需要將自己注冊到ServiceManager中,定義的服務也是在Android系統進程System中啟動。
比如說你自定義一個服務RemoteService.java
public class RemoteService extends IRemoteService.Stub{
......
}
那么Android系統進程System在啟動時,會創建一個ServiceThread線程來啟動系統中的關鍵服務,RemoteService就是在這個ServiceThread線程中啟動的。addService
方法將它注冊到ServiceManager。
public final class SystemServer {
......
private void run() {
......
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
服務的初始化
因為RemoteService繼承了IRemote.Stub類,而后者有繼承了Binder類,說以初始化的時候會調用Binder類的構造函數。
//framworks/base/core/java/android/os/Binder.java
public class Binder implement IBinder{
......
public Binder() {
init();
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
}
......
private native final void init();
}
init()方法是一個Jni函數。具體實現如下
//framworks/base/core/jni/android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
RemoteService創建過程中在C++層對應一個JavaBinderHolder對象,而這個JavaBBinderHolder對象通過其成員變量mBInder
持有一個類型為JavaBBinder的本地對象。而進程間通信就是通過這個本地對象來實現的。
注冊服務到ServiceManager中
ServiceManager的Java代理對象的成員函數addService實現如下
//framworks/base/core/java/android/os/ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
......
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
......
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
}
......
}
成員變量mRemote指向一個句柄只等于0的Java服務代理對象通過transact()方法可以向ServiceManager發送進程間他通信請求。
//framworks/base/core/java/android/os/Binder.java
public class BinderProxy implement IBinder{
.....
public native boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
}
}
這是一個JNI方法,前面有講過
//framworks/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);
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
target, obj, code);
bool time_binder_calls;
int64_t start_millis;
if (kEnableBinderSample) {
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
time_binder_calls = should_time_binder_calls();
if (time_binder_calls) {
start_millis = uptimeMillis();
}
}
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
至此Java服務啟動過程解析完成。
</br>
參考:
《Android系統源代碼情景分析》羅升陽