Android应用程序绑定服务(bindService)的过程

本文详细介绍了Android中应用程序内部绑定Service的过程,从ContextWrapper.bindService开始,经过ActivityThread、LoadedApk、ActivityManagerService等多个步骤,最终完成Service的启动、绑定和服务连接。涉及到的关键步骤包括ContextImpl.bindService、ActivityManagerService.bindService、ServiceDispatcher创建、Service的onCreate和onBind方法调用,以及ServiceConnection的onServiceConnected回调。
摘要由CSDN通过智能技术生成

Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部启动。本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动Service的方法。

Step 1. ContextWrapper.bindService

这个函数定义在frameworks/base/core/java/android/content/ContextWrapper.java文件中:

public class ContextWrapper extends Context {
     
    Context mBase;  
    ......  
  
    @Override  
    public boolean bindService(Intent service, ServiceConnection conn,  
            int flags) {
     
        return mBase.bindService(service, conn, flags);  
    }  
  
    ......  
}  

这里的mBase是一个ContextImpl实例变量,于是就调用ContextImpl的bindService函数来进一步处理。


Step 2. ContextImpl.bindService

这个函数定义在frameworks/base/core/java/android/app/ContextImpl.java文件中:

class ContextImpl extends Context {
     
    ......  
  
    @Override  
    public boolean bindService(Intent service, ServiceConnection conn,  
            int flags) {
     
        IServiceConnection sd;  
        if (mPackageInfo != null) {
     
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),  
                mMainThread.getHandler(), flags);  
        } else {
     
            ......  
        }  
        try {
     
            int res = ActivityManagerNative.getDefault().bindService(  
                mMainThread.getApplicationThread(), getActivityToken(),  
                service, service.resolveTypeIfNeeded(getContentResolver()),  
                sd, flags);  
            ......  
            return res != 0;  
        } catch (RemoteException e) {
     
            return false;  
        }  
    }  
  
    ......  
  
}  

这里的mMainThread是一个ActivityThread实例,通过它的getHandler函数可以获得一个Handler对象,有了这个Handler对象后,就可以把消息分发到ActivityThread所在的线程消息队列中去了。

我们先看一下ActivityThread.getHandler的实现:


Step 3. ActivityThread.getHandler

public final class ActivityThread {
     
    ......  
  
    final H mH = new H();  
  
    ......  
  
    private final class H extends Handler {
     
        ......  
  
        public void handleMessage(Message msg) {
     
            ......  
        }  
  
        ......  
    }  
  
    ......  
  
    final Handler getHandler() {
     
        return mH;  
    }  
  
    ......  
}  

这里返回的Handler是在ActivityThread类内部从Handler类继承下来的一个H类实例变量。

回到Step 2中的ContextImpl.bindService函数中,获得了这个Handler对象后,就调用mPackageInfo.getServiceDispatcher函数来获得一个IServiceConnection接口,这里的mPackageInfo的类型是LoadedApk。


Step 4. LoadedApk.getServiceDispatcher

这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:

final class LoadedApk {
     
    ......  
  
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,  
            Context context, Handler handler, int flags) {
     
        synchronized (mServices) {
     
            LoadedApk.ServiceDispatcher sd = null;  
            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);  
            if (map != null) {
     
                sd = map.get(c);  
            }  
            if (sd == null) {
     
                sd = new ServiceDispatcher(c, context, handler, flags);  
                if (map == null) {
     
                    map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();  
                    mServices.put(context, map);  
                }  
                map.put(c, sd);  
            } else {
     
                sd.validate(context, handler);  
            }  
            return sd.getIServiceConnection();  
        }  
    }  
  
    ......  
  
    static final class ServiceDispatcher {
     
        private final ServiceDispatcher.InnerConnection mIServiceConnection;  
        private final ServiceConnection mConnection;  
        private final Handler mActivityThread;  
        ......  
  
        private static class InnerConnection extends IServiceConnection.Stub {
     
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;  
            ......  
  
            InnerConnection(LoadedApk.ServiceDispatcher sd) {
     
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);  
            }  
  
            ......  
        }  
  
        ......  
  
        ServiceDispatcher(ServiceConnection conn,  
                Context context, Handler activityThread, int flags) {
     
            mIServiceConnection = new InnerConnection(this);  
            mConnection = conn;  
            mActivityThread = activityThread;  
            ......  
        }  
  
        ......  
  
        IServiceConnection getIServiceConnection() {
     
            return mIServiceConnection;  
        }  
  
        ......  
    }  
  
    ......  
}  

在getServiceDispatcher函数中,传进来的参数context是一个MainActivity实例,先以它为Key值在mServices中查看一下,是不是已经存在相应的ServiceDispatcher实例,如果有了,就不用创建了,直接取出来。在我们这个情景中,需要创建一个新的ServiceDispatcher。在创建新的ServiceDispatcher实例的过程中,将上面传下来ServiceConnection参数c和Hanlder参数保存在了ServiceDispatcher实例的内部,并且创建了一个InnerConnection对象,这是一个Binder对象,一会是要传递给ActivityManagerService的,ActivityManagerServic后续就是要通过这个Binder对象和ServiceConnection通信的。

函数getServiceDispatcher最后就是返回了一个InnerConnection对象给ContextImpl.bindService函数。回到ContextImpl.bindService函数中,它接着就要调用ActivityManagerService的远程接口来进一步处理了。


Step 5. ActivityManagerProxy.bindService

这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

class ActivityManagerProxy implements IActivityManager  
{
     
    ......  
  
    public int bindService(IApplicationThread caller, IBinder token,  
            Intent service, String resolvedType, IServiceConnection connection,  
            int flags) throws RemoteException {
     
        Parcel data = Parcel.obtain();  
        Parcel reply = Parcel.obtain();  
        data.writeInterfaceToken(IActivityManager.descriptor);  
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);  
        data.writeStrongBinder(token);  
        service.writeToParcel(data, 0);  
        data.writeString(resolvedType);  
        data.writeStrongBinder(connection.asBinder());  
        data.writeInt(flags);  
        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);  
        reply.readException();  
        int res = reply.readInt();  
        data.recycle();  
        reply.recycle();  
        return res;  
    }  
  
    ......  
}  

这个函数通过Binder驱动程序就进入到ActivityManagerService的bindService函数去了。


Step 6. ActivityManagerService.bindService

pub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值