Binder进程间通信-JAVA层

进程间通信基本原理

进程间通信原理

Binder是什么?

IPC(Inter-Process Communication 进程间通信)通信机制

什么时候需要用到进程间通信?

WebView访问,图片加载(下载),推送,双进程守护

系统进程(获取输入法服务,闹钟服务,摄相头服务,电话等)

为什么要多进程?

每个进程的内存是有限制的,在主进程中进行图片加载、下载内存容易耗尽产生OOM, 而且下载机制很容易出错,出错也会影响主进程。

进程间通信为什么要用到Binder机制?

内存划分
内存划分.png

进程间的用户空间是进程隔离的,内核空间是共享空间。一般32位系统, 内核空间为1G,用户空间为3G。一个进程空间4G。

用户空间可以通过内核空间进行访问。

Binder的作用和使用场景

Binder作用就是来实现进程之间通过内核空间实现通信的。

安卓增加Binder的原因

Binder与传统IPC对比

Binder 共享内存 Socket
性能 需要拷贝一次 无需拷贝 需要拷贝两次
特点 基于C/S 架构 易用性高 控制复杂,易用性差 基于C/S 架构 作为一款通用接口,其传输效率低,开销大
安全性 为每个APP分配UID 同时支持实名和匿名 依赖上层协议 访问接入点是开放的 不安全 依赖上层协议 访问接入点是开放的 不安全

性能

Binder只需要拷贝一次;共享内存无需拷贝;Socket需要拷贝两次

特点

Binder基于C/S架构,易用性高;共享内存控制复杂,易用性差;Socket基于C/S架构作为一款通用接口,传输效率低,开销大

安全性

Binder 为每个APP分配 UID同时支持实名和匿名;共享内存依赖上层协议,访问接入点是开放的,不安全;Socket 依赖上层协议,访问接入点是开放的,不安全

传统 IPC 传输数据

传统IPC.png
  1. 用户空间发送数据
  2. 通过系统调用copy_from_user()将数据从用户空间copy到内核缓存区(第1次copy)
  3. 另一个进程中:通过调用copy_from_user()将数据从内核缓存空间copy到用户空间(第2次copy)
  4. 接收数据

Binder 传输数据

Binder传输.png
  1. 用户空间发送数据
  2. 通过系统调用copy_from_user()将数据从用户空间copy到内核缓存区
  3. 因为存在映射关系(mmap内存映射将一个文件或者其它对象映射进内存),所以实现了跨进程通信

(内核缓存区和S端(接收端)的数据接收缓存区 映射同一块物理空间)

Binder源码分析

AIDL

AIDL: (Android Interface Definition Language) Android接口定义语言

每个服务都有个aidl与之对应。

Proxy:发送数据(客户端)

Stub:接收数据(服务端)

aidl.png

客户端:

在ServiceConnection中

获取aidl对象的方法(XXXAidl是定义的AIDL)

XXXAidl.Stub.asInterface(service);

asInterface跳转到了Stub中的asInterface方法

Stub继承了Binder并实现了aidl接口

public static abstract class Stub extends android.os.Binder implements com.lis.binder_learn.Aidl {
    private static final java.lang.String DESCRIPTOR = "com.lis.binder_learn.Aidl";

    /**
     * Construct the stub at attach it to the interface.
     */
    public Stub() {
        this.attachInterface(this, DESCRIPTOR);
    }

    /**
     * Cast an IBinder object into an com.lis.binder_learn.Aidl interface,
     * generating a proxy if needed.
     */
    public static com.lis.binder_learn.Aidl asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.lis.binder_learn.Aidl))) {
            return ((com.lis.binder_learn.Aidl) iin);
        }
        return new com.lis.binder_learn.Aidl.Stub.Proxy(obj);
    }

    @Override
    public android.os.IBinder asBinder() {
        return this;
    }

    @Override
    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
        java.lang.String descriptor = DESCRIPTOR;
        switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(descriptor);
                return true;
            }
            case TRANSACTION_addPerson: {
                data.enforceInterface(descriptor);
                com.lis.binder_learn.Person _arg0;
                if ((0 != data.readInt())) {
                    _arg0 = com.lis.binder_learn.Person.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }
                this.addPerson(_arg0);
                reply.writeNoException();
                return true;
            }
            case TRANSACTION_getPersonList: {
                data.enforceInterface(descriptor);
                java.util.List _result = this.getPersonList();
                reply.writeNoException();
                reply.writeTypedList(_result);
                return true;
            }
            default: {
                return super.onTransact(code, data, reply, flags);
            }
        }
    }

asInterface方法中queryLocalInterface是Binder.java中实现

public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
        if (mDescriptor != null && mDescriptor.equals(descriptor)) {
            return mOwner;
        }
        return null;
    }

在Stub的构造方法中,将自身和DESCRIPTOR(com.lis.binder_learn.Aidl 全类名)传到了Binder.java中

public Stub() {
    this.attachInterface(this, DESCRIPTOR);
}
public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
    mOwner = owner;
    mDescriptor = descriptor;
}

所以queryLocalInterface方法是查询保存到本地的descriptor是否相等,相等就返回了自身Aidl

但是客户端这里是不相等的,因为客服端没有调用Stub的构造承当,这里的传入的descriptor是个空。

(这一块是在服务端进行传入的Stub)

客服端不会始化Stub不传descriptor,服务端会初始化Stub传descriptor。

这里的查询比较是因为:Activity和Service有可能是同一进程当中的,如果是同一进程就不需要进行binder进行传输了。

if (((iin != null) && (iin instanceof com.lis.binder_learn.Aidl))) {
    return ((com.lis.binder_learn.Aidl) iin);
}
return new com.lis.binder_learn.Aidl.Stub.Proxy(obj);

这里如果是同一进程就直接返回aidl,如果不是同一进程就返回了Proxy。

mAidl = Aidl.Stub.asInterface(service);

这里客户端就拿到了proxy(mAidl)

mAidl.addPerson(new Person("张三", 1));

调用mAidl的方法,就进了Proxy中的方法中

Proxy是个实体类实现了aidl接口

private static class Proxy implements com.lis.binder_learn.Aidl {
    private android.os.IBinder mRemote;

    Proxy(android.os.IBinder remote) {
        mRemote = remote;
    }

    @Override
    public android.os.IBinder asBinder() {
        return mRemote;
    }

    public java.lang.String getInterfaceDescriptor() {
        return DESCRIPTOR;
    }
    //客户端传输

    @Override
    public void addPerson(com.lis.binder_learn.Person person) throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            if ((person != null)) {
                _data.writeInt(1);
                person.writeToParcel(_data, 0);
            } else {
                _data.writeInt(0);
            }
            boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
            if (!_status && getDefaultImpl() != null) {
                getDefaultImpl().addPerson(person);
                return;
            }
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public java.util.List getPersonList() throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.util.List _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            boolean _status = mRemote.transact(Stub.TRANSACTION_getPersonList, _data, _reply, 0);
            if (!_status && getDefaultImpl() != null) {
                return getDefaultImpl().getPersonList();
            }
            _reply.readException();
            _result = _reply.createTypedArrayList(com.lis.binder_learn.Person.CREATOR);
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }

    public static com.lis.binder_learn.Aidl sDefaultImpl;
}

_data就是发送到服务端的数据

_reply就是服务端返回的数据

@Override
public void addPerson(com.lis.binder_learn.Person person) throws android.os.RemoteException {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    try {
        _data.writeInterfaceToken(DESCRIPTOR);
        if ((person != null)) {
            _data.writeInt(1);
            person.writeToParcel(_data, 0);
        } else {
            _data.writeInt(0);
        }
        boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
        if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().addPerson(person);
            return;
        }
        _reply.readException();
    } finally {
        _reply.recycle();
        _data.recycle();
    }
}

这里做了个数据的校验

_data.writeInterfaceToken(DESCRIPTOR);

通过mRemote.transact方法,将数据发送给服务端,这时客户端线程挂起,直到服务端数据返回。这里的flags=0表示,客户端和服务端可以想到通信,1的话代表客户端发到服务端,服务端不能返回。

Stub.TRANSACTION_addPerson:因为客户端和服务端的AIDL是一样的,所以方法顺序是一样的。这里传入方法顺序数,就可以知道调用的哪个方法(整型)

boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);

transact方法在Binder.java中,调用 onTransact

public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
        int flags) throws RemoteException {
    if (false) Log.v("Binder", "Transact: " + code + " to " + this);

    if (data != null) {
        data.setDataPosition(0);
    }
    boolean r = onTransact(code, data, reply, flags);
    if (reply != null) {
        reply.setDataPosition(0);
    }
    return r;
}

这里会到服务端的Stub#onTransact方法

服务端:

@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
    java.lang.String descriptor = DESCRIPTOR;
    switch (code) {
        case INTERFACE_TRANSACTION: {
            reply.writeString(descriptor);
            return true;
        }
        case TRANSACTION_addPerson: {
            data.enforceInterface(descriptor);
            com.lis.binder_learn.Person _arg0;
            if ((0 != data.readInt())) {
                _arg0 = com.lis.binder_learn.Person.CREATOR.createFromParcel(data);
            } else {
                _arg0 = null;
            }
            this.addPerson(_arg0);
            reply.writeNoException();
            return true;
        }
        case TRANSACTION_getPersonList: {
            data.enforceInterface(descriptor);
            java.util.List _result = this.getPersonList();
            reply.writeNoException();
            reply.writeTypedList(_result);
            return true;
        }
        default: {
            return super.onTransact(code, data, reply, flags);
        }
    }
}

根据code 找到调用的哪个方法case TRANSACTION_addPerson

data.enforceInterface(descriptor);

这里根据descriptor进行校验

this.addPerson(_arg0);

这里的addPerson调用的是Service中实现的Stub()中addPerson方法

private IBinder mIBinder = new Aidl.Stub() {
    @Override
    public void addPerson(Person person) throws RemoteException {

        persons.add(person);
        Log.e("AidlService", "persons.size: "+persons.size());
    }

    @Override
    public List getPersonList() throws RemoteException {
        Log.e("AidlService", "getPersonList.size: "+persons.size());
        return persons;
    }
};

AIDL时序图:

时序图.png

最后通过_reply进行数据返回

如何获得另一个进程的对象

bindService中都 做了些什么?

bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
@Override
public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    return mBase.bindService(service, conn, flags);
}

最后调用了ContextImpl.bindService

@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
            getUser());
}

bindServiceCommon

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
        String instanceName, Handler handler, Executor executor, UserHandle user) {
    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
    IServiceConnection sd;
    if (conn == null) {
        throw new IllegalArgumentException("connection is null");
    }
    if (handler != null && executor != null) {
        throw new IllegalArgumentException("Handler and Executor both supplied");
    }
    if (mPackageInfo != null) {
        if (executor != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
        } else {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        }
    } else {
        throw new RuntimeException("Not supported in system context");
    }
    validateServiceIntent(service);
    try {
        IBinder token = getActivityToken();
        if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                && mPackageInfo.getApplicationInfo().targetSdkVersion
                < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            flags |= BIND_WAIVE_PRIORITY;
        }
        service.prepareToLeaveProcess(this);
        int res = ActivityManager.getService().bindIsolatedService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
        if (res < 0) {
            throw new SecurityException(
                    "Not allowed to bind to service " + service);
        }
        return res != 0;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
 //基于23的代码
 int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
static public IActivityManager getDefault() {
        return gDefault.get();
    }
public interface IActivityManager extends IInterface

IActivityManager继承自IInterface

public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

这样,IActivityManager=AIDL接口

private static final Singleton gDefault = new Singleton() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};
IBinder b = ServiceManager.getService("activity");

这里ServiceManager把我们调用的服务的IBinder返回。(这个IBinder就是AMS服务)

IActivityManager am = asInterface(b);

通过asInterface 返回 ,这里的am就是Proxy

就是ActivityManagerNative.getDefault()这里返回一个Proxy对象

asInterface会跑到Stub中去

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    /**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }
    ...

所以ActivityManagerNative 就是Stub

即:ActivityManagerNative== Stub

ActivityManagerNative$ActivityManagerProxy == Proxy

ActivityManagerProxy #bindService

public int bindService(IApplicationThread caller, IBinder token,
        Intent service, String resolvedType, IServiceConnection connection,
        int flags,  String callingPackage, int userId) 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);
    data.writeString(callingPackage);
    data.writeInt(userId);
    mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    int res = reply.readInt();
    data.recycle();
    reply.recycle();
    return res;
}

mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0); 跳到ActivityManagerNative#onTransact方法

case BIND_SERVICE_TRANSACTION: {
    data.enforceInterface(IActivityManager.descriptor);
    IBinder b = data.readStrongBinder();
    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();
    String callingPackage = data.readString();
    int userId = data.readInt();
    IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
    int res = bindService(app, token, service, resolvedType, conn, fl,
            callingPackage, userId);
    reply.writeNoException();
    reply.writeInt(res);
    return true;
}

bindService(app, token, service, resolvedType, conn, fl,callingPackage, userId); 这里的bindService是调用的真正的服务Service(这里使用的AMS服务)

public final class ActivityManagerService extends ActivityManagerNative

ActivityManagerService#bindService ====>ActivityManagerService#bindServiceLocked

  1. ActivityServices#bringUpServiceLocked()

    进程状态的1,2

  2. ActivityServices#requestServiceBindingLocked(s, b.intent, callerFg, true);

    进程状态的3,4

A进程访问B进程时的几种状态

进程的几种状态.png

bringUpServiceLocked()

2. app存在,但是Service没创建
if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } 

app创建了

if (app != null && app.thread != null) ` 代表B进程已经启动

realStartServiceLocked(r, app, execInFg); 启动服务

realStartServiceLocked中

app.thread.scheduleCreateService(r, r.serviceInfo,
        mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
        app.repProcState);

这里的app是应用进程,thread是ApplicationThread(ActivityThread#ApplicationThread)

public final void scheduleCreateService(IBinder token,
        ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
    updateProcessState(processState, false);
    CreateServiceData s = new CreateServiceData();
    s.token = token;
    s.info = info;
    s.compatInfo = compatInfo;

    sendMessage(H.CREATE_SERVICE, s);
}

进到了Handler

case CREATE_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
    handleCreateService((CreateServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;

创建服务的方法handleCreateService

private void handleCreateService(CreateServiceData data) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();

    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to instantiate service " + data.info.name
                + ": " + e.toString(), e);
        }
    }

    try {
        if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);

        Application app = packageInfo.makeApplication(false, mInstrumentation);
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
        service.onCreate();
        mServices.put(data.token, service);
        try {
            ActivityManagerNative.getDefault().serviceDoneExecuting(
                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
        } catch (RemoteException e) {
            // nothing to do.
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to create service " + data.info.name
                + ": " + e.toString(), e);
        }
    }
}

service = (Service) cl.loadClass(data.info.name).newInstance();--->AidlService 创建了我们的服务(通过类加载器,反射创建)

调用service生命周期,保存服务

service.attach(context, this, data.info.name, data.token, app,
        ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
1. 进程没有启动

app没有创建

if (app == null) {
    if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
            "service", r.name, false, isolated, false)) == null) {
        String msg = "Unable to launch app "
                + r.appInfo.packageName + "/"
                + r.appInfo.uid + " for service "
                + r.intent.getIntent() + ": process is bad";
        Slog.w(TAG, msg);
        bringDownServiceLocked(r);
        return msg;
    }
    if (isolated) {
        r.isolatedProc = app;
    }
}

进入到startProcessLocked中的

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);

创建进程

requestServiceBindingLocked

绑定服务:

requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind)

绑定与否 和rebind有关,走的同一个方法

try {
    bumpServiceExecutingLocked(r, execInFg, "bind");
    r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
            r.app.repProcState);
    if (!rebind) {
        i.requested = true;
    }
    i.hasBound = true;
    i.doRebind = false;
}

调用scheduleBindService方法==》ActivityThread#scheduleBindService

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;

    if (DEBUG_SERVICE)
        Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
                + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
    sendMessage(H.BIND_SERVICE, s);
}
case BIND_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
    handleBindService((BindServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (DEBUG_SERVICE)
        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) {
                    IBinder binder = s.onBind(data.intent);
                    ActivityManagerNative.getDefault().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
                ensureJitEnabled();
            } catch (RemoteException ex) {
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to bind to service " + s
                        + " with " + data.intent + ": " + e.toString(), e);
            }
        }
    }
}
IBinder binder = s.onBind(data.intent);

binder是调用的是AidlService中的onBind()返回的binder

public class AidlService extends Service {
    private ArrayList persons;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        persons = new ArrayList<>();
        Log.e("AidlService", "success onBind");
        return mIBinder;
    }
    ...
    }
ActivityManagerNative.getDefault().publishService(
        data.token, data.intent, binder);

ActivityManagerNative.getDefault()==>Proxy==>AMS中的publishService

ActivityManagerService#publishService

public void publishService(IBinder token, Intent intent, IBinder service) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    synchronized(this) {
        if (!(token instanceof ServiceRecord)) {
            throw new IllegalArgumentException("Invalid service token");
        }
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}

mServices.publishServiceLocked((ServiceRecord)token, intent, service);

publishServiceLocked中

try {
    c.conn.connected(r.name, service);
} catch (Exception e) {
    Slog.w(TAG, "Failure sending service " + r.name +
          " to connection " + c.conn.asBinder() +
          " (in " + c.binding.client.processName + ")", e);
}

c.conn.connected(r.name, service);==>调用到客户端的onServiceConnected()

参数就是服务端的IBinder

ConnectionRecord c

IServiceConnection conn

客户端:

bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

bindService时传入了ServiceConnection-->ContextImp#bindServiceCommon

IServiceConnection sd;
if (mPackageInfo != null) {
    sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
            mMainThread.getHandler(), flags);
}

这里传入了conn

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
        Context context, Handler handler, int flags) {
    synchronized (mServices) {
        LoadedApk.ServiceDispatcher sd = null;
        ArrayMap 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 ArrayMap();
                mServices.put(context, map);
            }
            map.put(c, sd);
        } else {
            sd.validate(context, handler);
        }
        return sd.getIServiceConnection();
    }
}

sd = new ServiceDispatcher(c, context, handler, flags);

这里传入了ServiceConnection,最后从sd.getIServiceConnection() 返回IServiceConnection

IServiceConnection getIServiceConnection() {
    return mIServiceConnection;
}
private final ServiceDispatcher.InnerConnection mIServiceConnection;

这里返回的是个InnerConnection对象

private static class InnerConnection extends IServiceConnection.Stub {
    final WeakReference mDispatcher;

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

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

上面的c.conn.connected就是调用的InnerConnection#connected方法,

而这个方法又调用了sd.connected

public void connected(ComponentName name, IBinder service) {
    if (mActivityThread != null) {
        mActivityThread.post(new RunConnection(name, service, 0));
    } else {
        doConnected(name, service);
    }
}
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) {
        mConnection.onServiceConnected(name, service);
    }
}
// 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) {
    mConnection.onServiceConnected(name, service);
}

这里就调到了connection的方法。

所以上面c.conn.connected(r.name, service)就是调用的ServiceConnection的onServiceConnected方法。

如何进行通信的

总结

总结.png

PS:进程知识补充

进程分为:

  • 前台进程
  • 可见进程
  • 服务进程
  • 后台进程
  • 空进程
进程.png

前台进程:

有一个Activity

  • ​ 正在交互

有一个Service

  • 绑定到正在交互的Activity
  • “前台运行”,startForeground()
  • 正在执行生命周期回调onCreate()

有一个BroadcastReceiver

  • 正在执行onReceive()

可见进程:

有一个Activity

  • 不在交互,但仍可见

有一个Service

  • 绑定到可见Activity

服务进程:

  • 普通Service

故而对耗时的比如上传等,新建一个Service比在Activity新建一个线程好的多。

后台进程:

  • 所有Activity都对用户不可见

会被保存在LRU列表中,即最近查看的最晚被终止

空进程:

系统有时候会使用空进程做为缓存,以缩短下一次在其中运行组建所需的启动时间

多进程的特性

  • 不同的内存空间,数据无法共享
  • 需要谨慎处理代码中的线程同步
  • 需要提防多进程并发导致的文件锁和数据库锁时效的问题

具体问题:

1. 静态成员和单例模式完全失效
2. 线程同步机制失效
3. SharedPreferences可靠性下降
4. Application会多次重建

如何判断进程的优先级

通过oom_adj 值,判断进程的优先级

不同手机的oom_adj 值 可能不一样

进程优先级.png

进程间通信方式

进程间通信方式对比.png

线程间通信

  1. 共享内存
  2. 文件、数据库
  3. Handler
  4. Java里的wait notify notifyAll

在非UI线程中更新UI

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable,long)
  • handler
  • AsyncTask

你可能感兴趣的:(Binder进程间通信-JAVA层)