Android筑基——Service的绑定过程之跨进程绑定(基于api21)

目录

1.前言

本文主要介绍在跨进程 Service 的绑定过程。

实际工作中,和其他 App 进行交互,多是通过跨进程绑定 Service 这种方式完成通信。笔者对这样的过程比较感兴趣,因此本篇文章的主题不是同进程绑定 Service,而是跨进程绑定 Servcie

因为涉及到跨进程,会涉及进程的创建步骤,所以本篇文章会比较长,希望同学们能够耐心看完。

2.正文

现在展示一下构成分析的代码,这里构建的分析场景是应用内在 Activity 页面里跨进程绑定一个 Service。

定义 ICompute.aidl 文件:

// ICompute.aidl
package com.wzc.chapter_9;

interface ICompute {
    int add(int a, int b);
}

创建 RemoteBindService

public class RemoteBindService extends Service {

    private static final String TAG = "RemoteBindService";

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: processName=" + MyUtils.getProcessName(this, Process.myPid()));
        return stub.asBinder();
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        Log.d(TAG, "onRebind: processName=" + MyUtils.getProcessName(this, Process.myPid()));
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: processName=" + MyUtils.getProcessName(this, Process.myPid()));
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: processName=" + MyUtils.getProcessName(this, Process.myPid()));
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: processName=" + MyUtils.getProcessName(this, Process.myPid()));
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: processName=" + MyUtils.getProcessName(this, Process.myPid()));
    }

    private final ICompute stub = new ICompute.Stub() {
        @Override
        public int add(int a, int b) throws RemoteException {
            return a + b;
        }
    };
}

AndroidManifest.xml 中注册 RemoteBindService

<application>
    <service
        android:name=".RemoteBindService"
        android:process="com.wzc.chapter_9.remote" />
</application>

需要注意的是,我们这里设置了 android:process 属性,这样 RemoteBindService 是运行在单独的进程里面了,进程名字为:com.wzc.chapter_9.remote

MainActivity 里面进行绑定服务的操作,并调用 add 方法执行远程调用:

private final ServiceConnection serviceConnection = new ServiceConnection() 
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        ICompute iCompute = ICompute.Stub.asInterface(service);
        try {
            int result = iCompute.add(1, 1);
            Log.d(TAG, "onServiceConnected: result=" + result + ", processName=" + MyUtils.getProcessName(MainActivity.this, Process.myPid()));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
};
public void bindService(View view) {
    Intent intent = new Intent(MainActivity.this, RemoteBindService.class);
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

点击绑定服务按钮后,打印日志如下:

D/RemoteBindService: onCreate: processName=com.wzc.chapter_9.remote
D/RemoteBindService: onBind: processName=com.wzc.chapter_9.remote
D/MainActivity: onServiceConnected: 
D/MainActivity: onServiceConnected: result=2, processName=com.wzc.chapter_9

可以看到,RemoteBindService 确实运行在 com.wzc.chapter_9.remote 进程里面了。

现在,我们一起开始学习 Service 的绑定过程吧。

2.1 ContextWrapper.bindService() 方法

我们在 MainActivity 里面调用了 bindService() 方法,而 Activity 继承了 ContextWrapper,实际调用的是 ContextWrapperbindService() 方法。

  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • ServiceConnection conn, ServiceConnection 对象
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
@Override
public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    return mBase.bindService(service, conn, flags);
}

那么,mBase 是谁呢?它是一个 ContextImpl 对象。详细可以查看Android筑基——Service的启动过程之同进程启动(基于api21)的 2.1 部分。

调用包装类 ContextWrapperbindService() 方法,内部真正调用的是 ContextImplbindService() 方法。

2.2 ContextImpl.bindService() 方法

  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • ServiceConnection conn, ServiceConnection 对象
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
@Override
public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    // 见[2.3]
    return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}

2.3 ContextImpl.bindServiceCommon() 方法

  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • ServiceConnection conn, ServiceConnection 对象
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
  • UserHandle user, Process.myUserHandle() 返回的 UserHandle 对象
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
        UserHandle user) {
    IServiceConnection sd;
    ...
    if (mPackageInfo != null) {
		// 获取 InnerConnection 对象,见[2.3.1]
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                mMainThread.getHandler(), flags);
    } else {
        ...
    }
    validateServiceIntent(service);
    try {
        IBinder token = getActivityToken();
        ...
        service.prepareToLeaveProcess();
		// 调用到这里,去绑定服务,见[2.4]
        int res = ActivityManagerNative.getDefault().bindService(
            mMainThread.getApplicationThread(), getActivityToken(),
            service, service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, user.getIdentifier());
        ...
        return res != 0;
    } catch (RemoteException e) {
        return false;
    }
}

ActivityManagerNative.getDefault() 实际上获取的是一个 ActivityManagerProxy 对象,也就是客户端进程获取到的 Binder 代理对象。详细可以查看Android筑基——Service的启动过程之同进程启动(基于api21)的 2.3.1 部分。

该方法主要作用:getServiceDispatcher 方法把 ServiceConnection 对象包装成 InnerConnection 对象,再向 AMS 发起绑定服务的请求。

2.3.1 LoadedApk.getServiceDispatcher() 方法

  • ServiceConnection c, ServiceConnection 对象
  • Context context, MainActivity.this 对象
  • Handler handler, ActivityThread 里的 mH 对象
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
public final class LoadedApk {
	// mServices 是一个 ArrayMap 对象,key 为 Context 对象,value 为 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> 对象
	// 其 value 也是一个 ArrayMap 对象,key 为 ServiceConnection 对象,value 为 LoadedApk.ServiceDispatcher 对象。
	private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
		
	public final IServiceConnection getServiceDispatcher(ServiceConnection c,
			Context context, Handler handler, int flags) {
		synchronized (mServices) {
			LoadedApk.ServiceDispatcher sd = null;
			// 根据 context,从 mServices 取出 map 对象
			ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
			if (map != null) {
				// map 对象不为空,根据 ServiceConnection 对象,获取 LoadedApk.ServiceDispatcher 对象
				sd = map.get(c);
			}
			if (sd == null) { // 获取的 LoadedApk.ServiceDispatcher 对象为空
				// 创建一个 ServiceDispatcher 对象,见[2.3.2]
				sd = new ServiceDispatcher(c, context, handler, flags);
				// 并把创建好的 ServiceDispatcher 对象存储到数据结构中。
				if (map == null) {
					map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
					mServices.put(context, map);
				}
				map.put(c, sd);
			} else {
				sd.validate(context, handler);
			}
			// 从 ServiceDispatcher 对象获取 IServiceConnection 对象。
			return sd.getIServiceConnection();
		}
	}
	// ServiceDispatcher 是 LoadedApk 的静态内部类
	static final class ServiceDispatcher {...}
}

getServiceDispatcher() 方法,会接收 ServiceConnection 对象,但是它的返回并非如其名字所写的那样会返回一个 ServiceDispatcher 对象,实际上它返回的是一个 InnerConnection 对象(这个对象通过弱引用持有一个 ServiceDispatcher 对象)。

我们知道,ServiceConnection 是用于获取服务是否连接,是否断开的接口,在调用绑定服务的方法 bindService() 时,会传入一个 ServiceConnection 对象,这样在服务绑定或者断开时,就会回调此接口的方法。

那么,为什么我们传递给 AMS 的却是 InnterConnection 对象,而不是 ServiceConnection 对象呢?

这是因为 ServiceConnection 仅仅是一个普通的 java 接口:

public interface ServiceConnection {
    public void onServiceConnected(ComponentName name, IBinder service);
    public void onServiceDisconnected(ComponentName name);
}

而服务的绑定有可能是跨进程的,ServiceConnection 肯定不具有跨进程传输的能力,所以 Android 封装了具有跨进程传输能力的 InnerConnection 来完成 ServiceConnection 不能完成的工作。
IServiceConnection.aidl 如下:

package android.app;
import android.content.ComponentName;
oneway interface IServiceConnection {
    @UnsupportedAppUsage
    void connected(in ComponentName name, IBinder service);
}

2.3.2 LoadedApk.ServiceDispatcher 类

public final class LoadedApk {
	static final class ServiceDispatcher {
        private final ServiceDispatcher.InnerConnection mIServiceConnection;
        private final ServiceConnection mConnection;
        private final Context mContext;
        private final Handler mActivityThread;
        private final int mFlags;
		// InnerConnection 是 ServiceDispatcher 的私有静态内部类
        private static class InnerConnection extends IServiceConnection.Stub {
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service) throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service);
                }
            }
        }

        ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
			// 创建 InnerConnection 对象
            mIServiceConnection = new InnerConnection(this);
			// 使用成员变量 mConnection 持有 ServiceConnection 对象
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
            mFlags = flags;
        }

        IServiceConnection getIServiceConnection() {
            return mIServiceConnection;
        }
    }
}

ServiceDispatcherLoadedApk 的静态内部类,而 InnerConnection 又是 ServiceDispatcher 的私有静态内部类。

需要注意的是,InnerConnection 是继承于 IServiceConnection.Stub 类,因此它是一个 binder 服务端类。

通过 getIServiceConnection() 返回的就是一个 InnerConnection binder 服务端对象。

2.4 ActivityManagerProxy.bindService() 方法

  • IApplicationThread caller, ActivityThread 里的 ApplicationThread 对象,是 binder 服务端。
  • IBinder token, getActivityToken() 返回的 token 值
  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • String resolvedType, resolveTypeIfNeeded 返回的值
  • IServiceConnection connection, LoadedApk.ServiceDispatcher.InnerConnection 对象,是 binder 服务端
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
  • int userId
public int bindService(IApplicationThread caller, IBinder token,
        Intent service, String resolvedType, IServiceConnection connection,
        int flags, int userId) throws RemoteException {
   	...
    mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
    ...
    return res;
}

mRemote.transact() 是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ActivityManagerNativeonTransact() 方法。

2.5 ActivityManagerNative.onTransact() 方法

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
	switch (code) {
		...
		case BIND_SERVICE_TRANSACTION: {
			data.enforceInterface(IActivityManager.descriptor);
			IBinder b = data.readStrongBinder();
			// 获取的是 ApplictionThreadProxy 对象,是客户端对象
			IApplicationThread app = ApplicationThreadNative.asInterface(b);
			IBinder token = data.readStrongBinder();
			Intent service = Intent.CREATOR.createFromParcel(data);
			String resolvedType = data.readString();
			b = data.readStrongBinder();
			int fl = data.readInt();
			int userId = data.readInt();
			// 获取 IServiceConnection 接口的客户端对象
			IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
			// 见[2.6]
			int res = bindService(app, token, service, resolvedType, conn, fl, userId);
			reply.writeNoException();
			reply.writeInt(res);
			return true;
		}
		}
	}
}

现在,已经进入到 system_server 进程了,onTransact() 方法是运行在服务端进程的 binder 线程池里面。

客户端进程(即 App 进程)通过 Binder 接口(即 IActivityManager 接口)向服务端进程(即 ActivityManagerService 进程)发起请求服务;
服务端进程(即 ActivityManagerService 进程)通过 Binder 接口(即 IApplicationThread 接口)向客户端进程(即 App 进程)发起请求服务。

这样,就构成了客户端进程和服务端进程的双向通信结构了。

ActivityManagerNative 是抽象类,bindService() 是它的一个抽象方法。

ActivityManagerService 继承了 ActivityManagerNative,实现了 bindService() 这个抽象方法。

2.6 ActivityManagerService.bindService() 方法

  • IApplicationThread caller, ActivityThreadProxy 对象,是 binder 客户端。
  • IBinder token, getActivityToken() 返回的 token 值
  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • String resolvedType, resolveTypeIfNeeded 返回的值
  • IServiceConnection connection, IServiceConnection.Stub.Proxy 对象,是 binder 客户端
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
  • int userId
public final class ActivityManagerService extends ActivityManagerNative
{
	final ActiveServices mServices;
	public ActivityManagerService(Context systemContext) {
		mServices = new ActiveServices(this);
	}
	public int bindService(IApplicationThread caller, IBinder token,
			Intent service, String resolvedType,
			IServiceConnection connection, int flags, int userId) {
		synchronized(this) {
		    // 见[2.7]
			return mServices.bindServiceLocked(caller, token, service, resolvedType,
					connection, flags, userId);
		}
	}
}

2.7 ActiveServices.bindServiceLocked() 方法

  • IApplicationThread caller, ActivityThreadProxy 对象,是 binder 客户端。
  • IBinder token, getActivityToken() 返回的 token 值
  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • String resolvedType, resolveTypeIfNeeded 返回的值
  • IServiceConnection connection, IServiceConnection.Stub.Proxy 对象,是 binder 客户端
  • int flags, Context.BIND_AUTO_CREATE = 0x0001
  • int userId
int bindServiceLocked(IApplicationThread caller, IBinder token,
        Intent service, String resolvedType,
        IServiceConnection connection, int flags, int userId) {
	// 获取发起方进程记录对象
    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
    ActivityRecord activity = null;
	// token 不为空,代表发起方有 activity 上下文,
	// 本次我们是在 MainActivity 里发起绑定的,所以 token 不等于 null。
    if (token != null) {
        activity = ActivityRecord.isInStackLocked(token);
        if (activity == null) { // activity 是 MainActivity,不为 null。
            return 0;
        }
    }
    int clientLabel = 0;
    PendingIntent clientIntent = null;
    final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
	// 检索服务信息,见[2.7.1]
    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType,
                Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
    if (res == null) {
        return 0;
    }
    if (res.record == null) {
        return -1;
    }
    ServiceRecord s = res.record;
    final long origId = Binder.clearCallingIdentity();
    try {
		// 取消服务的重启调度
        if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
        }
        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
			// 更新当前的 service 的活动时间
            s.lastActivity = SystemClock.uptimeMillis();
            ...
        }
		// 通过 ServiceRecord 对象检索 AppBindRecord,见[2.7.2]
        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
		// 创建 ConnectionRecord 对象
        ConnectionRecord c = new ConnectionRecord(b, activity,
                connection, flags, clientLabel, clientIntent);
		// 把新创建的 ConnectionRecord 对象保存到各种列表的数据结构中。
        IBinder binder = connection.asBinder();
        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            s.connections.put(binder, clist);
        }
        clist.add(c);
        b.connections.add(c);
        if (activity != null) {
            if (activity.connections == null) {
                activity.connections = new HashSet<ConnectionRecord>();
            }
            activity.connections.add(c);
        }
        b.client.connections.add(c);
        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
            b.client.hasAboveClient = true;
        }
        if (s.app != null) { // s.app 目前是 null
            updateServiceClientActivitiesLocked(s.app, c, true);
        }
        clist = mServiceConnections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            mServiceConnections.put(binder, clist);
        }
        clist.add(c);
        if ((flags&Context.BIND_AUTO_CREATE) != 0) { // 进入此分支
            s.lastActivity = SystemClock.uptimeMillis();
			// 调用到这里,去拉起服务,见[2.8]
			// 因为本次是跨进程绑定服务,目标进程不存在,本次目标进程会创建成功,该方法返回 null,不会进入此分支。
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
                return 0;
            }
        }
        ...
		// 这时 service 的进程已经创建成功了,所以 s.app 不为 null 了
		// b.intent.received 在 publishServiceLocked 方法才被置为 true,此处为 false。 
		if (s.app != null && b.intent.received) { // 本次不会进入此分支
			...
		} else if (!b.intent.requested) { // 进入此分支,但是由于目标进程不存在,所以会直接返回。
			requestServiceBindingLocked(s, b.intent, callerFg, false);
		}
		getServiceMap(s.userId).ensureNotStartingBackground(s);
    } finally {
    }
    return 1;
}

本方法的作用是:获取了 ServiceRecord 对象,发起拉起服务的请求,服务绑定后,向客户端进程回调连接成功。

2.7.1 ActiveServices.retrieveServiceLocked() 方法

  • Intent service, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • String resolvedType, 通过 resolveTypeIfNeeded() 方法获得
  • int callingPid, 调用者的 pid
  • int callingUid, 调用者的 uid
  • int userId, 通过 UserHandle.getIdentifier() 方法获得
  • boolean createIfNeeded, true
  • boolean callingFromFg 应该是 true
private ServiceLookupResult retrieveServiceLocked(Intent service,
        String resolvedType, int callingPid, int callingUid, int userId,
        boolean createIfNeeded, boolean callingFromFg) {
    ServiceRecord r = null;
	// 获取 userId
    userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
            false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
	// 根据 userId,获取 ServiceMap 对象
    ServiceMap smap = getServiceMap(userId);
	// 尝试从 ServiceMap 对象里获取 ServiceRecord 对象
    final ComponentName comp = service.getComponent();
    if (comp != null) {
        r = smap.mServicesByName.get(comp);
    }
    if (r == null) {
        Intent.FilterComparison filter = new Intent.FilterComparison(service);
        r = smap.mServicesByIntent.get(filter);
    }
	// 没有获取到 ServiceRecord 对象,会进入 if 分支
    if (r == null) {
        try {
			// 从清单文件里解析出 ServiceInfo 对象
            ResolveInfo rInfo =
                AppGlobals.getPackageManager().resolveService(
                            service, resolvedType,
                            ActivityManagerService.STOCK_PM_FLAGS, userId);
            ServiceInfo sInfo =
                rInfo != null ? rInfo.serviceInfo : null;
            if (sInfo == null) {
                return null;
            }
            ComponentName name = new ComponentName(
                    sInfo.applicationInfo.packageName, sInfo.name);
            if (userId > 0) {
                if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                        sInfo.name, sInfo.flags)
                        && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                    userId = 0;
                    smap = getServiceMap(0);
                }
                sInfo = new ServiceInfo(sInfo);
                sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
            }
            r = smap.mServicesByName.get(name);
            if (r == null && createIfNeeded) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(service.cloneFilter());
                ServiceRestarter res = new ServiceRestarter();
          
				// 创建 ServiceRecord 对象。
                r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                res.setService(r);
                smap.mServicesByName.put(name, r);
                smap.mServicesByIntent.put(filter, r);
                for (int i=mPendingServices.size()-1; i>=0; i--) {
                    ServiceRecord pr = mPendingServices.get(i);
                    if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                            && pr.name.equals(name)) {
                        mPendingServices.remove(i);
                    }
                }
            }
        } catch (RemoteException ex) {
        }
    }
    if (r != null) {
		// 作权限检查
        if (mAm.checkComponentPermission(r.permission,
                callingPid, callingUid, r.appInfo.uid, r.exported)
                != PackageManager.PERMISSION_GRANTED) {
           ...
        }
		// 作 intent firewall 检查
        if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                resolvedType, r.appInfo)) {
            return null;
        }
		// 把 ServiceRecord 封装在 ServiceLookupResult 对象里面返回。
        return new ServiceLookupResult(r, null);
    }
    return null;
}

该方法的主要作用:查询 ServiceRecord 对象,如果不存在,就创建一个 ServiceRecord。最后封装在 ServiceLookupResult 里面返回。

2.7.2 ServiceRecord.retrieveAppBindingLocked() 方法

  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • ProcessRecord app 发起方进程记录对象
final class ServiceRecord extends Binder {
	final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
			= new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
			
	public AppBindRecord retrieveAppBindingLocked(Intent intent,
			ProcessRecord app) {
		Intent.FilterComparison filter = new Intent.FilterComparison(intent);
		// 根据 filter,从 bindings 里获取 IntentBindRecord 对象。
		IntentBindRecord i = bindings.get(filter);
		if (i == null) {
			// 创建一个新的 IntentBindRecord 对象
			i = new IntentBindRecord(this, filter);
			bindings.put(filter, i);
		}
		AppBindRecord a = i.apps.get(app);
		if (a != null) {
			return a;
		}
		// 创建 AppBindRecord 对象,封装了 ServiceRecord 对象,intent 以及调用方进程记录对象。
		a = new AppBindRecord(this, i, app);
		i.apps.put(app, a);
		return a;
	}
}

IntentBindRecord.java 如下:

final class IntentBindRecord {
    final ServiceRecord service;
    final Intent.FilterComparison intent; // 
    final ArrayMap<ProcessRecord, AppBindRecord> apps
            = new ArrayMap<ProcessRecord, AppBindRecord>();
        
    IntentBindRecord(ServiceRecord _service, Intent.FilterComparison _intent) {
        service = _service;
        intent = _intent;
    }
}

AppBindRecord.java 如下:

final class AppBindRecord {
    final ServiceRecord service;    
    final IntentBindRecord intent;  
    final ProcessRecord client;     

    final ArraySet<ConnectionRecord> connections = new ArraySet<>();

    AppBindRecord(ServiceRecord _service, IntentBindRecord _intent,
            ProcessRecord _client) {
        service = _service;
        intent = _intent;
        client = _client;
    }
}

2.8 ActiveServices.bringUpServiceLocked() 方法

  • ServiceRecord r, 当前 Service 的记录对象
  • int intentFlags, 为 0,没有设置过
  • boolean execInFg, true
  • boolean whileRestarting, false
private final String bringUpServiceLocked(ServiceRecord r,
        int intentFlags, boolean execInFg, boolean whileRestarting) {
    // r.app 为 null,不会进入此分支
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
    ...
	// 我们正在拉起这个 service,所以 service 不应再处于正在重启状态。
    if (mRestartingServices.remove(r)) {
        clearRestartingIfNeededLocked(r);
    }
	// 确保这个 service 不再被认为是延迟的,我们现在正在启动它。
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }
    // 确保服务的拥有者已经启动了,否则就停止启动服务.
    if (mAm.mStartedUsers.get(r.userId) == null) {
        ...
        return msg;
    }
    // 服务在被启动,设置 package 停止状态为 false.
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(
                r.packageName, false, r.userId);
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
    }
    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName; // 这里获取的就是 android:process 属性的值: com.wzc.chapter_9.remote
    ProcessRecord app;
    if (!isolated) { // 进入此分支
		// 获取目标进程,返回为 null。
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (app != null && app.thread != null) { // app 为 null,所以不会进入此分支。
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (RemoteException e) {
            }
        }
    } else {
        ...
    }
	// 目标进程没有运行,就开启目标进程,并且当进程起来时排队执行这个 service.
    if (app == null) {
		// 调用到这里,通过 AMS 来开启新的进程,见[2.9]
		// 本次进程会开启成功,所以 app 不会为 null,所以不会进入此分支
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = ""; // 省略 msg 的内容
            bringDownServiceLocked(r);
            return msg;
        }
    }
   	// 把 ServiceRecord 对象添加到 mPendingServices 队列里面
    if (!mPendingServices.contains(r)) {
        mPendingServices.add(r);
    }
    if (r.delayedStop) {
        // Oh and hey we've already been asked to stop!
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r);
        }
    }
    return null;
}

该方法的主要作用是:

  1. 判断ServiceRecord对象的目标进程成员变量是否存在,存在则直接发送相应的参数即可;
  2. 不存在,则查询目标进程是否存在,存在则走 realStartServiceLocked,否则就通过 AMS 去开启新的进程。

2.9 ActivityManagerService.startProcessLocked() 方法

  • String processName, “com.wzc.chapter_9.remote”
  • ApplicationInfo info, 清单文件中的 application 节点信息
  • boolean knownToBeDead, true
  • int intentFlags, 为 0,没有设置过
  • String hostingType, “service”
  • ComponentName hostingName, Service 的组件名对象,即包名 + 类名的组合
  • boolean allowWhileBooting, false
  • boolean isolated, false
  • boolean keepIfLarge false
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);

调用 startProcessLocked 的重载方法:

  • String processName, “com.wzc.chapter_9.remote”
  • ApplicationInfo info, 清单文件中的 application 节点信息
  • boolean knownToBeDead, true
  • int intentFlags, 为 0,没有设置过
  • String hostingType, “service”
  • ComponentName hostingName, Service 的组件名对象,即包名 + 类名的组合
  • boolean allowWhileBooting, false
  • boolean isolated, false
  • int isolatedUid, 0
  • boolean keepIfLarge false
  • String abiOverride, null
  • String entryPoint, null
  • String[] entryPointArgs, null
  • Runnable crashHandler, null
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    if (!isolated) { // isolated 为 false,进入此分支
		// 获取进程名为 "com.wzc.chapter_9.remote" 的进程记录对象,这里还没有,所以返回 null。
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
    } else {
        ...
    }
	
    if (app != null && app.pid > 0) { // app 为 null,不会进入此分支
        ...
    }
    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;
    if (!isolated) { // 进入此分支
        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { // intentFlags 为 0,不会进入此分支
            ...
        } else { // 进入此分支
            mProcessCrashTimes.remove(info.processName, info.uid);
            if (mBadProcesses.get(info.processName, info.uid) != null) {
                mBadProcesses.remove(info.processName, info.uid);
                if (app != null) {
                    app.bad = false;
                }
            }
        }
    }
    if (app == null) { // 进入此分支
		// 创建新的 ProcessRecord 对象,见[2.9.1]。
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        app.crashHandler = crashHandler;
        if (app == null) {
            return null;
        }
        mProcessNames.put(processName, app.uid, app);
        ...
    } else {
        ...
    }
	// 如果系统还没有就绪,那么就推迟启动进程直到系统就绪。
    if (!mProcessesReady
            && !isAllowedWhileBooting(info)
            && !allowWhileBooting) {
        if (!mProcessesOnHold.contains(app)) {
            mProcessesOnHold.add(app);
        }
        return app;
    }
	// 启动新进程,见[2.10]
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    return (app.pid != 0) ? app : null;
}

该方法的主要作用是:创建一个 ProcessRecord 对象,再调用 startProcessLocked 的重载方法来开启新的进程。

2.9.1 ActivityManagerService.newProcessRecordLocked() 方法

  • ApplicationInfo info, 清单文件中的 application 节点信息
  • String customProcess, “com.wzc.chapter_9.remote”
  • boolean isolated, false
  • int isolatedUid, 0
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
        boolean isolated, int isolatedUid) {
    String proc = customProcess != null ? customProcess : info.processName;
    BatteryStatsImpl.Uid.Proc ps = null;
    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
    int uid = info.uid;
    if (isolated) { // false,不会进入此分支
        ...
    }
	// 创建一个 ProcessRecord 对象而已。
    return new ProcessRecord(stats, info, proc, uid);
}

2.10 ActivityManagerService.startProcessLocked() 方法

  • ProcessRecord app, 新创建的 ProcessRecord 对象
  • String hostingType, “service”
  • String hostingNameStr, Service 的组件名对象转换成的字符串,即"com.wzc.chapter_9/.RemoteBindService"
  • String abiOverride, null
  • String entryPoint, null
  • String[] entryPointArgs, null
private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    long startTime = SystemClock.elapsedRealtime();
    if (app.pid > 0 && app.pid != MY_PID) { // app.pid 为 0,不会进入此分支
        ...
    }
    mProcessesOnHold.remove(app);
    updateCpuStats();
    try {
        int uid = app.uid;
        int[] gids = null;
        int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
        if (!app.isolated) { // isolated 为 false,会进入此分支
            ...
        }
        ...
        boolean isActivityProcess = (entryPoint == null); // true
		// entryPoint 是 null,所以 entryPoint 会被赋值为 "android.app.ActivityThread"
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
		// 开启进程:请求 zygote 去开启进程,见[2.11]
        Process.ProcessStartResult startResult = Process.start(entryPoint,
                app.processName, uid, uid, gids, debugFlags, mountExternal,
                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                app.info.dataDir, entryPointArgs);
        ...
		// 设置 ProcessRecord app 的成员变量
        app.setPid(startResult.pid);
        app.usingWrapper = startResult.usingWrapper;
        app.removed = false;
        app.killed = false;
        app.killedByAm = false;
        synchronized (mPidsSelfLocked) {
            this.mPidsSelfLocked.put(startResult.pid, app);
            if (isActivityProcess) {
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        }
    } catch (RuntimeException e) {
		...
    }
}

2.11 Process.start() 方法

  • final String processClass, “android.app.ActivityThread”
  • final String niceName, “com.wzc.chapter_9.remote”
  • int uid,
  • int gid,
  • int[] gids,
  • int debugFlags,
  • int mountExternal,
  • int targetSdkVersion, 目标 sdk 版本
  • String seInfo,
  • String abi, 架构
  • String instructionSet, 指令集
  • String appDataDir,
  • String[] zygoteArgs, null
public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] zygoteArgs) {
    try {
		// 通过 zygote 开启进程
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

system_server 进程里,调用 Process.start() 方法,通过 socket 向 zygote 进程发送创建新进程的请求;

在 zygote 进程里面,在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;

新的进程创建后,执行handleChildProc方法,最后调用ActivityThread.main()方法。

这部分详细请参考理解Android进程创建流程

本文会直接跳到 ActivityThread.main()方法继续分析。

2.12 ActivityThread.main() 方法

public static void main(String[] args) {
    ...
    // 准备主线程的 Looper 对象
    Looper.prepareMainLooper();
	// 创建 ActivityThread 对象
    ActivityThread thread = new ActivityThread();
	// 调用 ActivityThread 对象的 attach 方法
    thread.attach(false);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    AsyncTask.init();
    // 运行消息队列
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

2.13 ActivityThread.attach() 方法

  • boolean system, false,表示不是系统进程,而是普通应用进程
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) { // system 为 false,进入此分支
        ...
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // mgr 实际上是 ActivityManagerProxy 对象
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
        ...
    } else {
        ...
    }
    ...
}

2.14 ActivityManagerService.attachApplication() 方法

  • IApplicationThread thread, ApplicationThreadProxy 对象
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

2.15 ActivityManagerService.attachApplicationLocked() 方法

  • IApplicationThread thread, ApplicationThreadProxy 对象
  • int pid, 新的 service 进程的 pid
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    ProcessRecord app;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
			// 获取到之前存储的 ProcessRecord 对象,不为 null。
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }
    if (app == null) { // 不会进入此分支
        ...
    }
    // 给 IApplicationThread 设置死亡代理   
    final String processName = app.processName;
    try {
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        startProcessLocked(app, "link fail", processName);
        return false;
    }
    app.makeActive(thread, mProcessStats);
    app.curAdj = app.setAdj = -100;
    app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.forcingToForeground = null;
    updateProcessForegroundLocked(app, false, false);
    app.hasShownUi = false;
    app.debugging = false;
    app.cached = false;
	// 移除开启超时的消息
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    
    try {
        ...
        ApplicationInfo appInfo = app.instrumentationInfo != null
                ? app.instrumentationInfo : app.info;
        app.compat = compatibilityInfoForPackageLocked(appInfo);
        ...
		// 创建新进程的 Application 对象
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                mCoreSettingsObserver.getCoreSettingsLocked());
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
       ...
    }
    // Remove this record from the list of starting applications.
    mPersistentStartingProcesses.remove(app);
    mProcessesOnHold.remove(app);
    boolean badApp = false;
    boolean didSomething = false;
    // See if the top visible activity is waiting to run in this process...
    // 查看是否有顶可见的 activity 正在等待运行在该进程里面。
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }
    // Find any services that should be running in this process...
    // 找到应该允许在该进程里面的任何 service。
    if (!badApp) {
        try {
			// 调用到这里,见[2.16]
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // Check if a next-broadcast receiver is in this process...
    // 检查是否下一个广播接收者在这个进程里面
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // Check whether the next backup agent is in this process...
    if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        } catch (Exception e) {
            badApp = true;
        }
    }
    if (badApp) {
        app.kill("error during init", true);
        handleAppDiedLocked(app, false, true);
        return false;
    }
    if (!didSomething) {
        updateOomAdjLocked();
    }
    return true;
}

该方法的作用是:

  1. 创建新进程的 Application 对象;
  2. 依次查看是否有要待运行的 activity,service,receiver 等。

2.16 ActiveServices.attachApplicationLocked() 方法

  • ProcessRecord proc, 新进程的进程记录对象
  • String processName, “com.wzc.chapter_9.remote”
boolean attachApplicationLocked(ProcessRecord proc, String processName)
        throws RemoteException {
    boolean didSomething = false;
	// mPendingServices 里有一个 ServiceRecord 对象,在 bringUpServiceLocked 方法里添加的。
    if (mPendingServices.size() > 0) {
        ServiceRecord sr = null;
        try {
            for (int i=0; i<mPendingServices.size(); i++) {
                sr = mPendingServices.get(i);
                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName))) {
                    continue;
                }
                mPendingServices.remove(i);
                i--;
                proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                        mAm.mProcessStats);
				// 调用到这里,真正打开 service,见[2.17]
                realStartServiceLocked(sr, proc, sr.createdFromFg);
                didSomething = true;
            }
        } catch (RemoteException e) {
            throw e;
        }
    }
	...
    return didSomething;
}

2.17 ActiveServices.realStartServiceLocked() 方法

  • ServiceRecord r, RemoteBindService 对应的 service 记录对象
  • ProcessRecord app, 新进程对应的进程记录对象
  • boolean execInFg, true
private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
	// 把新的进程记录对象赋值给 service 记录对象的 app 成员变量
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    app.services.add(r);
    bumpServiceExecutingLocked(r, execInFg, "create");
    boolean created = false;
    try {
        ...
		// 创建 service,最终会回调 Service 的 onCreate 方法,见[2.18]
        // app 是一个 ProcessRecord 对象
        // app.thread 是一个 ApplicationThreadProxy 对象,属于 binder 客户端。
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        mAm.appDiedLocked(app);
    } finally {
        ...
    }
	// 请求绑定 service,见[2.23]
    requestServiceBindingsLocked(r, execInFg);
    updateServiceClientActivitiesLocked(app, null, true);
    ...
    sendServiceArgsLocked(r, execInFg, true);
    ...
}

2.18 ApplicationThreadProxy.scheduleCreateService() 方法

  • IBinder token, ServiceRecord 对象,它继承了 Binder,而 Binder 实现了 IBinder 接口。
  • ServiceInfo info, 清单文件中的 service 节点信息
  • CompatibilityInfo compatInfo,
  • int processState
class ApplicationThreadProxy implements IApplicationThread {
	public final void scheduleCreateService(IBinder token, ServiceInfo info,
        CompatibilityInfo compatInfo, int processState) throws RemoteException {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		data.writeStrongBinder(token);
		info.writeToParcel(data, 0);
		compatInfo.writeToParcel(data, 0);
		data.writeInt(processState);
		// 调用到这里,远程调用 ApplicationThreadNative 的 onTransact() 方法,见[2.19]
		mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
				IBinder.FLAG_ONEWAY);
		data.recycle();
	}
}

mRemote.transact() 是服务端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 客户端 ApplicationThreadNativeonTransact() 方法。

2.19 ApplicationThreadNative.onTransact() 方法

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
	@Override
	public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
			throws RemoteException {
		case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
			data.enforceInterface(IApplicationThread.descriptor);
			IBinder token = data.readStrongBinder();
			ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
			CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
			int processState = data.readInt();
			// 见[2.20]
			scheduleCreateService(token, info, compatInfo, processState);
			return true;
		}
	}
}

ApplicationThreadNative 是一个抽象类,scheduleCreateService() 方法是一个抽象方法;ApplicationThread 继承了 ApplicationThreadNative 类,实现了 scheduleCreateService() 这个抽象方法。

因此,scheduleCreateService() 方法的实现是在 ApplicationThread 中。

2.20 ApplicationThread.scheduleCreateService() 方法

  • IBinder token, ServiceRecord 对象,它继承了 Binder,而 Binder 实现了 IBinder 接口。
  • ServiceInfo info, 清单文件中的 service 节点信息
  • CompatibilityInfo compatInfo,
  • int processState
private class ApplicationThread extends ApplicationThreadNative {
	public final void scheduleCreateService(IBinder token,
        ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
		updateProcessState(processState, false);
		// 把 token,info 等封装在 CreateServiceData 对象中。
		CreateServiceData s = new CreateServiceData();
		s.token = token;
		s.info = info;
		s.compatInfo = compatInfo;
		sendMessage(H.CREATE_SERVICE, s);
	}
}

2.21 H.handleMessage() 方法

public final class ActivityThread {
	final H mH = new H();
	private class H extends Handler {
		public void handleMessage(Message msg) {
			case CREATE_SERVICE:
				Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
				// 调用到这里,见[2.22]
				handleCreateService((CreateServiceData)msg.obj);
				break;
		}
	}
}

这里就从客户端进程的 Binder 线程切到了主线程。

2.22 ActivityThread.handleCreateService() 方法

  • CreateServiceData data 封装了token,info 等信息的对象
private void handleCreateService(CreateServiceData data) {
    unscheduleGcIdler();
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
		// 通过反射创建目标 Service 对象
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
    }
    try {
		// 创建 ContextImpl 对象
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
		// 创建 Application 对象或者直接返回已有的 Application 对象
        Application app = packageInfo.makeApplication(false, mInstrumentation);
		// 调用 Service 对象的 attach 方法,把 Context 对象,AMS,ProcessRecord 等和 Service 对象关联起来。
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
		// 回调 Service 对象的 onCreate 方法
        service.onCreate();
		// 将 service 的 token 和 对象存在 ActivityThread 的 map 中。
        mServices.put(data.token, service);
        try {
            ActivityManagerNative.getDefault().serviceDoneExecuting(
                    data.token, 0, 0, 0);
        } catch (RemoteException e) {
            // nothing to do.
        }
    } catch (Exception e) {
    }
}

该方法的主要作用是:回调了 Service 的 onCreate() 方法。

2.23 ActiveServices.requestServiceBindingsLocked() 方法

从[2.17] 调用而来的。

final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
        = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
    for (int i=r.bindings.size()-1; i>=0; i--) {
        IntentBindRecord ibr = r.bindings.valueAt(i);
        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
            break;
        }
    }
}

retrieveAppBindingLocked() 方法中给 bindings 集合添加了一个元素,所以这里对 bindings 遍历,可以走进去。

内部调用的是:

private final boolean requestServiceBindingLocked(ServiceRecord r,
        IntentBindRecord i, boolean execInFg, boolean rebind) {
    if (r.app == null || r.app.thread == null) {
        return false;
    }
    // i.requested 在 publishServiceLocked 方法才会赋值为 true
    if ((!i.requested || rebind) && i.apps.size() > 0) { // 会进入此分支
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            // r 是 ServiceRecord 对象
            // r.app 是 ProcessRecord 对象
            // r.app.thread 是 ApplicationThreadProxy 对象。
            // 调用到这里,见[2.24]
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                    r.app.repProcState);
            if (!rebind) {
                i.requested = true;
            }
            i.hasBound = true;
            i.doRebind = false;
        } catch (RemoteException e) {
            return false;
        }
    }
    return true;
}

2.24 ApplicationThreadProxy.scheduleBindService() 方法

  • IBinder token, ServiceRecord 对象
  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • boolean rebind, false
  • int processState,
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
        int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    intent.writeToParcel(data, 0);
    data.writeInt(rebind ? 1 : 0);
    data.writeInt(processState);
    mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}

mRemote.transact() 是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ApplicationThreadNativeonTransact() 方法。

2.25 ApplicationThreadNative.onTransact() 方法

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
	@Override
	public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
			throws RemoteException {
        case SCHEDULE_BIND_SERVICE_TRANSACTION: {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            boolean rebind = data.readInt() != 0;
            int processState = data.readInt();
            scheduleBindService(token, intent, rebind, processState);
            return true;
        }
	}
}

ApplicationThreadNative 是一个抽象类,scheduleBindService() 方法是一个抽象方法;ApplicationThread 继承了 ApplicationThreadNative 类,实现了 scheduleBindService() 这个抽象方法。

因此,scheduleBindService() 方法的实现是在 ApplicationThread 中。

2.26 ApplicationThread.scheduleBindService() 方法

  • IBinder token, ServiceRecord 对象
  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • boolean rebind, false
  • int processState,
public final void scheduleBindService(IBinder token, Intent intent,
        boolean rebind, int processState) {
    updateProcessState(processState, false);
    BindServiceData s = new BindServiceData();
    s.token = token;
    s.intent = intent;
    s.rebind = rebind;
    sendMessage(H.BIND_SERVICE, s);
}

tokenintentrebind 封装在 BindServiceData 里面,通过 Handler 发送到主线程。

2.27 H.handleMessage() 方法

public final class ActivityThread {
	final H mH = new H();
	private class H extends Handler {
		public void handleMessage(Message msg) {
			case BIND_SERVICE:
                handleBindService((BindServiceData)msg.obj);
                break;		
		}
	}
}

这里就从客户端进程的 Binder 线程切到了主线程。

2.28 ActivityThread.handleBindService() 方法

private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) { // rebind 为 false,进入此分支
                    // 回调 Service 的 onBind() 方法
                    IBinder binder = s.onBind(data.intent);
                    // ActivityManagerNative.getDefault() 是 ActivityManagerProxy 对象
                    ActivityManagerNative.getDefault().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, 0, 0, 0);
                }
            } catch (RemoteException ex) {
            }
        } catch (Exception e) {
            
        }
    }
}

2.29 ActivityManagerProxy.publishService() 方法

  • IBinder token, ServiceRecord 对象
  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • IBinder service, new ICompute.Stub(){} 匿名内部类
public void publishService(IBinder token,
        Intent intent, IBinder service) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(token);
    intent.writeToParcel(data, 0);
    data.writeStrongBinder(service);
    mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

mRemote.transact() 是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ActivityManagerNativeonTransact() 方法。

2.30 ActivityManagerNative.onTransact() 方法

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
	switch (code) {
		...
		case PUBLISH_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder service = data.readStrongBinder();
            // 通过 AMS 发布服务,见[2.31]
            publishService(token, intent, service);
            reply.writeNoException();
            return true;
        }
		}
	}
}

2.31 ActivityManagerService.publishService() 方法

  • IBinder token, ServiceRecord 对象
  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • IBinder service, new ICompute.Stub(){} 匿名内部类
public void publishService(IBinder token, Intent intent, IBinder service) {
    ...
    synchronized(this) {
        ...
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}

mServices 是一个 ActiveServices 对象。

2.32 ActiveServices.publishServiceLocked() 方法

  • IBinder token, ServiceRecord 对象
  • Intent intent, new Intent(MainActivity.this, RemoteBindService.class) 对象
  • IBinder service, new ICompute.Stub(){} 匿名内部类
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (r != null) {
            Intent.FilterComparison filter
                    = new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true;
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                        if (!filter.equals(c.binding.intent.intent)) {
                            continue;
                        }
                        try {
                            // 调用到这里,见[2.33]
                            // c 是 ConnectionRecord 对象
                            // c.conn 是 IServiceConnection 对象,实际上是 IServiceConnection.Stub.Proxy 对象,是 binder 客户端。
                            c.conn.connected(r.name, service);
                        } catch (Exception e) {
                        }
                    }
                }
            }
            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}

c.connIServiceConnection 对象,实际上是 IServiceConnection.Stub.Proxy 对象,是 binder 客户端;经过 binder 驱动,会调用到发起方进程的服务端 IServiceConnection.Stub 对象,即 InnerConnection 对象。

2.33 InnerConnection.connected() 方法

  • ComponentName name, Service 的组件名对象,即包名 + 类名的组合
  • IBinder service, ICompute 对应的 BinderProxy 对象
private static class InnerConnection extends IServiceConnection.Stub {
    final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
    InnerConnection(LoadedApk.ServiceDispatcher sd) {
        mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
    }
    public void connected(ComponentName name, IBinder service) throws RemoteException {
        LoadedApk.ServiceDispatcher sd = mDispatcher.get();
        if (sd != null) {
            sd.connected(name, service);
        }
    }
}

2.34 ServiceDispatcher.connected() 方法

  • ComponentName name, Service 的组件名对象,即包名 + 类名的组合
  • IBinder service, ICompute 对应的 BinderProxy 对象
public void connected(ComponentName name, IBinder service) {
    if (mActivityThread != null) { // 进入此分支
        mActivityThread.post(new RunConnection(name, service, 0));
    } else {
        doConnected(name, service);
    }
}

2.35 RunConnection.run() 方法

  • ComponentName name, Service 的组件名对象,即包名 + 类名的组合
  • IBinder service, ICompute 对应的 BinderProxy 对象
  • int command, 0
private final class RunConnection implements Runnable {
    RunConnection(ComponentName name, IBinder service, int command) {
        mName = name;
        mService = service;
        mCommand = command;
    }
    public void run() {
        if (mCommand == 0) {
            doConnected(mName, mService);
        } else if (mCommand == 1) {
            doDeath(mName, mService);
        }
    }
    final ComponentName mName;
    final IBinder mService;
    final int mCommand;
}

2.36 ServiceDispatcher.doConnected() 方法

  • ComponentName name, Service 的组件名对象,即包名 + 类名的组合
  • IBinder service, ICompute 对应的 BinderProxy 对象
public void doConnected(ComponentName name, IBinder service) {
    ServiceDispatcher.ConnectionInfo old;
    ServiceDispatcher.ConnectionInfo info;
    synchronized (this) {
        if (mForgotten) {
            // We unbound before receiving the connection; ignore
            // any connection received.
            return;
        }
        old = mActiveConnections.get(name);
        if (old != null && old.binder == service) {
            // Huh, already have this one.  Oh well!
            return;
        }
        if (service != null) {
            // A new service is being connected... set it all up.
            mDied = false;
            info = new ConnectionInfo();
            info.binder = service;
            info.deathMonitor = new DeathMonitor(name, service);
            try {
                service.linkToDeath(info.deathMonitor, 0);
                mActiveConnections.put(name, info);
            } catch (RemoteException e) {
                // This service was dead before we got it...  just
                // don't do anything with it.
                mActiveConnections.remove(name);
                return;
            }
        } else {
            // The named service is being disconnected... clean up.
            mActiveConnections.remove(name);
        }
        if (old != null) {
            old.binder.unlinkToDeath(old.deathMonitor, 0);
        }
    }
    // If there was an old service, it is not disconnected.
    if (old != null) {
        mConnection.onServiceDisconnected(name);
    }
    // If there is a new service, it is now connected.
    if (service != null) {
        // 回调 ServiceConnection 的 onServiceConnected 方法
        mConnection.onServiceConnected(name, service);
    }
}

3.最后

本文到这里就结束了,希望能够帮助到同学们。

4.参考

  1. 图解 | 一图摸清Android应用进程的启动
  2. bindService启动过程分析-袁辉辉
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

willwaywang6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值