红橙Darren视频笔记 从AIDL Demo分析Android源码走向

一 AIDL demo

1.1 服务端搭建

新建AIDL文件

// IUserCalc.aidl
package com.example.aidlserver;

// Declare any non-default types here with import statements

interface IUserCalc {
    String getUserName();
    String getUserPassword();
}

创建Service

/**
 * Created by hjcai on 2021/4/25.
 */
public class UserService extends Service {
    private static final String TAG = "UserService";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind: ");
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    }

    private final IUserCalc.Stub mBinder = new IUserCalc.Stub() {
        @Override
        public String getUserName() throws RemoteException {
            Log.e(TAG, "getUserName: ");
            return "hjcai";
        }

        @Override
        public String getUserPassword() throws RemoteException {
            Log.e(TAG, "getUserPassword: ");
            return "12341234";
        }
    };
}

在清单文件中配置service和sharedUserId

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.aidlserver"
    android:sharedUserId="com.id.hjcai">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LearnEassyJoke">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".UserService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.example.aidl.server" />
            </intent-filter>
        </service>
    </application>

</manifest>

服务端搭建完毕

1.2 客户端搭建

拷贝服务端的AIDL
创建服务端Service代理的包装类

/**
 * Created by hjcai on 2021/4/25.
 */
class ServerServiceWrapper {
    private static final String TAG = "ServerServiceWrapper";
    private IUserCalc mCalcAidl;
    public static ServerServiceWrapper instance;

    private ServerServiceWrapper() {

    }

    public static ServerServiceWrapper getInstance() {

        if (instance == null) {
            synchronized (ServerServiceWrapper.class) {
                if (instance == null) {
                    instance = new ServerServiceWrapper();
                }
            }
        }
        return instance;
    }

    public boolean bindService(Context context) {
        Intent intent = new Intent();
        intent.setAction("com.example.aidl.server");
        // 需要明确指明server端包名 否则抛出如下异常
        // Service Intent must be explicit: Intent { act=com.example.aidl.server }
        intent.setPackage("com.example.aidlserver");
        return context.bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
    }

    public void unbindService(Context context) {
        if(mCalcAidl != null){
            context.unbindService(mServiceConn);
        }
    }

    // 返回服务端的代理
    private ServiceConnection mServiceConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG, "onServiceConnected: ");
            mCalcAidl = IUserCalc.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "onServiceDisconnected: ");
            mCalcAidl = null;
        }
    };

    public String getName() {
        try {
            return mCalcAidl == null ? "" : mCalcAidl.getUserName();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return "";
    }

    public String getPass() {
        try {
            return mCalcAidl == null ? "" : mCalcAidl.getUserPassword();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return "";
    }
}

创建测试xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="bind"
        android:text="bind" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="unBind"
        android:text="unbind" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getName"
        android:text="getName" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getPass"
        android:text="getPass" />

</LinearLayout>

创建测试Activity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MyApp";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void bind(View view) {
        boolean res = ServerServiceWrapper.getInstance().bindService(this);
        Log.e(TAG, "bind: "+res);
    }

    public void unBind(View view) {
        ServerServiceWrapper.getInstance().unbindService(this);
        Log.e(TAG, "unBind");
    }

    public void getName(View view) {
        String name = ServerServiceWrapper.getInstance().getName();
        Log.e(TAG, "getName: " + name);
    }

    public void getPass(View view) {
        String pass = ServerServiceWrapper.getInstance().getPass();
        Log.e(TAG, "getPass: " + pass);
    }
}

修改客户端清单文件 加入sharedUserId

android:sharedUserId="com.id.hjcai"

其中 核心类为服务端的Service 客户端的Wrapper

1.3运行效果

分别点击
bind getName getPass unBind得到运行结果:

2021-04-26 09:54:46.372 27151-27151/com.example.aidlclient E/MyApp: bind: true
2021-04-26 09:54:46.376 28183-28183/com.example.aidlserver E/UserService: onBind: 
2021-04-26 09:54:46.385 27151-27151/com.example.aidlclient E/ServerServiceWrapper: onServiceConnected: 

2021-04-26 09:54:51.992 28183-28225/com.example.aidlserver E/UserService: getUserName: 
2021-04-26 09:54:51.992 27151-27151/com.example.aidlclient E/MyApp: getName: hjcai

2021-04-26 09:54:59.618 28183-28225/com.example.aidlserver E/UserService: getUserPassword: 
2021-04-26 09:54:59.619 27151-27151/com.example.aidlclient E/MyApp: getPass: 12341234

2021-04-26 09:55:04.601 27151-27151/com.example.aidlclient E/MyApp: unBind
2021-04-26 09:55:04.601 28183-28183/com.example.aidlserver E/UserService: onUnbind: 

二 AIDL大致流程(基于API28)

2.1 分析一下大致流程

客户端调用bindService Server返回 Service对象

    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind: ");
        return mBinder;//服务端返回了存根(stub)类
    }

    private final IUserCalc.Stub mBinder = new IUserCalc.Stub() {
    ...
    }

客户端onServiceConnected回调中 将存根类转换为代理类

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG, "onServiceConnected: ");
            mCalcAidl = IUserCalc.Stub.asInterface(service);
        }

接着客户端可以通过代理Service类调用远程service的方法

下面分析具体的流程

2.2 调用bindService后 Server端执行onBind 之后 Client端执行onServiceConnected

2021-04-26 09:54:46.372 27151-27151/com.example.aidlclient E/MyApp: bind: true
2021-04-26 09:54:46.376 28183-28183/com.example.aidlserver E/UserService: onBind: 
2021-04-26 09:54:46.385 27151-27151/com.example.aidlclient E/ServerServiceWrapper: onServiceConnected:

从client的bindService到server的onBind

	// activity
	context.bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);

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

	// Context的具体实现类是ContextImpl
	// ContextImpl.java
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
    }

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            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);
            // 以下是重点
            // 结合ActivityManager的代码分析 可知ActivityManager.getService()得到是IActivityManager对象
            // 那么需要找到IActivityManager的bindService具体实现类
            int res = ActivityManager.getService().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, 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();
        }
    }
    
	// ActivityManager.java
    public static IActivityManager getService() {
        // 结合下面的IActivityManagerSingleton赋值代码 可知getService返回的是包装好的IBinder的IActivityManager对象
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

	// IActivityManager是一个接口 其实现类是ActivityManagerService 查找具体的bindService方法
    public int bindService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
        enforceNotIsolatedCaller("bindService");

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

        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }

        synchronized(this) {
            // 重点
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }

	// bindServiceLocked方法内容颇多 我们只关注代码最后一部分
	// ActiveServices.java
	int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
    ...
    if (s.app != null && b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.
                try {
                    c.conn.connected(s.name, b.intent.binder, false);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure sending service " + s.shortName
                            + " to connection " + c.conn.asBinder()
                            + " (in " + c.binding.client.processName + ")", e);
                }

                // If this is the first app connected back to this binding,
                // and the service had previously asked to be told when
                // rebound, then do so.
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    // 重点在这
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
        		// 重点在这
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }
    ...
    }

    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        if (r.app == null || r.app.thread == null) {
            // If service is not currently running, can't yet bind.
            return false;
        }
        if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
                + " rebind=" + rebind);
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                // 重点!//scheduleBindService无法点进去看,那么看看thread是什么
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
                // Keep the executeNesting count accurate.
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                throw e;
            } catch (RemoteException e) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                return false;
            }
        }
        return true;
    }

	// 我们经过 ServiceRecord 在ProcessRecord发现thread的真面目
	ProcessRecord app;  
	// ProcessRecord.java
    IApplicationThread thread;  // the actual proc...  may be null only if
                                // 'persistent' is true (in which case we
                                // are in the process of launching the app)

	// IApplicationThread的实现类是ApplicationThread ApplicationThread又是ActivityThread的内部类
	// 因此我们找到ActivityThread 打开后找到ApplicationThread 再查看ApplicationThread的scheduleBindService方法
	// ActivityThread.java
        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());
            // 重点 发送handler消息
            sendMessage(H.BIND_SERVICE, s);
        }

        public void handleMessage(Message msg) {
            switch (msg.what) {
                    ...
            	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) {
                        // 重点 调用了Service的onBind方法 第一个目标达成!!!!!!!!!1
                        IBinder binder = s.onBind(data.intent);
                        // 前面我们知道IActivityManager是一个接口 其实现类是ActivityManagerService
                        // 因此我们知道publishService具体实现在ActivityManagerService
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ensureJitEnabled();
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to bind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

	// ActivityManagerService.java
    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);
        }
    }

	// ActiveService.java
    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
        try {
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                    + " " + intent + ": " + service);
            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)) {
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Not publishing to: " + c);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Published intent: " + intent);
                                continue;
                            }
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                            try {
                                // 重点 我们需要知道connected方法的实现
                                // 需要查看conn的具体定义
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
                                Slog.w(TAG, "Failure sending service " + r.name +
                                      " to connection " + c.conn.asBinder() +
                                      " (in " + c.binding.client.processName + ")", e);
                            }
                        }
                    }
                }

                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

	// ConnectionRecord.java
	final IServiceConnection conn; //这东西看起来有些熟悉 我们在ContextImpl中看到过
	// ContextImpl.java
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;//这个对象
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        ...
     }
     
	// LoadedApk.java
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
                sd = map.get(c);
            }
            if (sd == null) {
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
                if (map == null) {
                    map = new ArrayMap<>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();// 查看sd对象类型
        }
    }

        IServiceConnection getIServiceConnection() {// sd 是IServiceConnection类型
            return mIServiceConnection;
        }

		// 继续查看mIServiceConnection的定义
		// 最终发现 c.conn.connected(r.name, service, false);中的connn是InnerConnection对象
		private final ServiceDispatcher.InnerConnection mIServiceConnection;
		
		// 我们继续看connected的方法
        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, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
                // 这里最终也会调用doConnected方法
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

       public void doConnected(ComponentName name, IBinder service, boolean dead) {
            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.
                    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 now disconnected.
            if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
            if (dead) {
                mConnection.onBindingDied(name);
            }
            // If there is a new viable service, it is now connected.
            if (service != null) {
                // 被调用!!!
                mConnection.onServiceConnected(name, service);
            } else {
                // The binding machinery worked, but the remote returned null from onBind().
                mConnection.onNullBinding(name);
            }
        }

小结一下调用顺序:

    //Context.java
	public abstract boolean bindService(@RequiresPermission Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags);

    //ContextImpl.java (Context.java实现类)
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
    }

	private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
            ...
            int res = ActivityManager.getService().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
    }
    
	//需要知道ActivityManager.getService()返回的对象 才能知道调用谁的bindService方法
	//ActivityManager.java 
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
	//问题转换为需要知道IActivityManager的实现类 才能知道调用谁的bindService方法
	//IActivityManager是一个接口 其实现类是ActivityManagerService
	//ActivityManagerService.java
	public int bindService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
        ...
    	return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
    }

	//AvtiveServices.java
	int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
    ...
                        if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }
    }

    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    ...
        r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
    }

	// 想知道scheduleBindService的实现 要知道thread是什么
	ProcessRecord app;  //app的定义
	//跟进ProcessRecord 查到thread的定义
	//ProcessRecord.java
	IApplicationThread thread;
	//IApplicationThread的实现类是ApplicationThread ApplicationThread又是ActivityThread的内部类
	//因此我需要从ActivityThread内找出ApplicationThread 并查看其中的scheduleBindService方法
        public final void scheduleBindService(IBinder token, Intent intent,
                boolean rebind, int processState) {
            ...
            sendMessage(H.BIND_SERVICE, s);
        }

	//在ActivityThread中查找BIND_SERVICE关键字
                case BIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                    handleBindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

	//跟进handleBindService
    private void handleBindService(BindServiceData data) {
                        IBinder binder = s.onBind(data.intent);
        				//!!!!!!!
        				//第一步达成!!onBind被调用
        				//前面我们分析 ActivityManager.getService()返回的对象就是ActivityManagerService
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
    }
	//查看ActivityManagerService的publishService
	//ActivityManagerService
    public void publishService(IBinder token, Intent intent, IBinder service) {
	...
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }
	//ActiveServices
    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    	c.conn.connected(r.name, service, false);
    }

	//想知道connected方法内容 需要知道conn的真实对象
	//ConnectionRecord
	final IServiceConnection conn;
	//IServiceConnection在ContextImpl中出现过
	IServiceConnection sd;
	//它具体的赋值在
	sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);

	//LoadedApk.java
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        ...
    	return sd.getIServiceConnection();
    }

    IServiceConnection getIServiceConnection() {
        return mIServiceConnection;
    }

	mIServiceConnection = new InnerConnection(this);
	//破案了 mPackageInfo.getServiceDispatcher返回的类型是InnerConnection
	//conn的类型其实是InnerConnection 查看InnerConnection.connected
            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
                //最终也会调用doConnected方法
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

        public void doConnected(ComponentName name, IBinder service, boolean dead) {
            ...
                mConnection.onServiceConnected(name, service);
        }

至此我们知道了客户端调用bindService 服务端onBind 客户端onServiceConnected调用的顺序了
简单来说客户端的具体信息在调用bindService时被存储在ContextImpl的connection中 后面通过 ActivityManagerService查询service并进行bind操作,完了又通过ActivityManagerService告知客户端绑定成功与否,告知是通过connection进行通知的

2.3 IUserCalc.java

在进一步分析之前我们先看一下Android Studio根据IUserCalc.aidl为我们生成的IUserCalc.java的大致内容

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package com.example.aidlserver;
// Declare any non-default types here with import statements
public interface IUserCalc extends android.os.IInterface
{
  /** Default implementation for IUserCalc. */
  public static class Default implements com.example.aidlserver.IUserCalc
  {
    @Override public java.lang.String getUserName() throws android.os.RemoteException
    {
      return null;
    }
    @Override public java.lang.String getUserPassword() throws android.os.RemoteException
    {
      return null;
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  // end Default

  /** Local-side IPC implementation stub class. */
  /**
   * 本地跨进程IPC实现 存根类
   * 包含几个静态变量(多用于识别调用端 调用的是哪个方法)
   * 几个方法 和一个静态内部类
   */
  // 内部类 Stub,继承了Binder,所以Stub就是一个Binder类 同时实现了IUserCalc 因此需要实现两个方法getUserName getUserPassword
  // 具体实现在Stub内部类 Proxy中
  public static abstract class Stub extends android.os.Binder implements com.example.aidlserver.IUserCalc
  {
    // Binder唯一标识,一般用当前aidl的完整包名+类名表示
    private static final java.lang.String DESCRIPTOR = "com.example.aidlserver.IUserCalc";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      // 关联指定接口和Binder
      this.attachInterface(this, DESCRIPTOR);//this代表接口  DESCRIPTOR代表Binder
    }
    /**
     * Cast an IBinder object into an com.example.aidlserver.IUserCalc interface,
     * generating a proxy if needed.
     *
     * 将IBinder转化为com.example.aidlserver.IUserCalc的接口对象
     * 代码分析:如果客户端和服务端同进程,则返回服务端的Stub对象本身 否则返回封装后的Stub.Proxy对象
     */
    public static com.example.aidlserver.IUserCalc asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      // 尝试从本地实现接口接收binder对象,如果得到的是null,你就需要从服务器端得到Binder对象,来转化成客户端所需的AIDL对象,即需要实例化proxy类来通过transact方法收集回调
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.example.aidlserver.IUserCalc))) {
        // 无需跨进程
        return ((com.example.aidlserver.IUserCalc)iin);
      }
      // 跨进程case
      return new com.example.aidlserver.IUserCalc.Stub.Proxy(obj);
    }

    //返回当前binder对象
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }

    // 运行在服务器端
    // onTransact只有当客户端和服务端不在同一个进程时才会调用
    // code代表请求类型 data中存放请求的参数,之后执行指定方法,
    // reply是服务器返回的结果,flags标明是否有返回值,0为有(双向),1为没有(单向),
    // 执行完毕向reply写入结果,如果有的话,return值代表返回成功或失败
    // 方法运行在服务端的binder线程池,客户端请求后通过底层代码将请求封装后交由该方法处理
    @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_getUserName:
        {
          data.enforceInterface(descriptor);
          java.lang.String _result = this.getUserName();
          reply.writeNoException();
          reply.writeString(_result);
          return true;
        }
        case TRANSACTION_getUserPassword:
        {
          data.enforceInterface(descriptor);
          java.lang.String _result = this.getUserPassword();
          reply.writeNoException();
          reply.writeString(_result);
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }

    //代理类
    private static class Proxy implements com.example.aidlserver.IUserCalc
    {
      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;
      }

      //运行在客户端,运行步骤如下
      //1创建输入型参数data和输出型参数reply,注意他们都是parcel类型的
      //2创建返回值对象result(如果有的话)
      //3将参数写入data(如果有参数)
      //4调用transact发起远程请求,接着当前线程挂起

      //5远程服务端的onTransact调用并返回结果
      //6挂起的线程继续执行,从reply中取出返回结果result(如果有的话),并返回result
      @Override public java.lang.String getUserName() throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.lang.String _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getUserName, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().getUserName();
          }
          _reply.readException();
          _result = _reply.readString();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }

      //执行过程和getUserName一样 只不过调用方法的参数不一样
      @Override public java.lang.String getUserPassword() throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.lang.String _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getUserPassword, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().getUserPassword();
          }
          _reply.readException();
          _result = _reply.readString();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      public static com.example.aidlserver.IUserCalc sDefaultImpl;
    }

    // 两个int值,用于标记调用的是哪个接口 如果IUserCalc有多个方法 这里会增加静态int值
    static final int TRANSACTION_getUserName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getUserPassword = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    public static boolean setDefaultImpl(com.example.aidlserver.IUserCalc impl) {
      // Only one user of this interface can use this function
      // at a time. This is a heuristic to detect if two different
      // users in the same process use this function.
      if (Stub.Proxy.sDefaultImpl != null) {
        throw new IllegalStateException("setDefaultImpl() called twice");
      }
      if (impl != null) {
        Stub.Proxy.sDefaultImpl = impl;
        return true;
      }
      return false;
    }
    public static com.example.aidlserver.IUserCalc getDefaultImpl() {
      return Stub.Proxy.sDefaultImpl;
    }
  }
  // 接口里定义的两个方法
  public java.lang.String getUserName() throws android.os.RemoteException;
  public java.lang.String getUserPassword() throws android.os.RemoteException;
}

下面我们就继续分析客户端调用getName的调用过程

2.4 调用接口分析

2021-04-26 09:54:51.992 28183-28225/com.example.aidlserver E/UserService: getUserName: 
2021-04-26 09:54:51.992 27151-27151/com.example.aidlclient E/MyApp: getName: hjcai
	  mCalcAidl.getUserName();

	  //Android studio根据AIDL生成的java文件
      @Override public java.lang.String getUserName() throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.lang.String _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          // 走这里 这里会挂起当前线程 等待远程的回复
          boolean _status = mRemote.transact(Stub.TRANSACTION_getUserName, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().getUserName();
          }
          _reply.readException();
          _result = _reply.readString();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      
	// Binder.java
    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);
        }
        // 走这里 调用远程Server端的onTransact方法
        boolean r = onTransact(code, data, reply, flags);
        if (reply != null) {
            reply.setDataPosition(0);
        }
        return r;
    }

	//调用远程端的onTransact方法 根据传进的code(方法名标记)调用对应的方法 写入reply 返回
    @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_getUserName:
        {
          data.enforceInterface(descriptor);
          java.lang.String _result = this.getUserName();//这里调用远程Service的方法
          reply.writeNoException();
          reply.writeString(_result);
          return true;
        }
        case TRANSACTION_getUserPassword:
        {
          data.enforceInterface(descriptor);
          java.lang.String _result = this.getUserPassword();
          reply.writeNoException();
          reply.writeString(_result);
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }
    
	// 之前客户端Proxy执行到这里在等待
	boolean _status = mRemote.transact(Stub.TRANSACTION_getUserName, _data, _reply, 0);
	// 服务端onTransact执行完毕后 这里可以继续执行了 得到服务端的返回

AIDL是使用binder的一个经典案例 binder本身是Android的一个非常重要的跨进程通信机制,它远比我们目前看到的复杂得多,比如它还设计ServiceManager binder.c等,比如binder的数据传输大小是有限制的,这次是跟着视频分析出来这些调用步骤的,更深入的还没有能力分析,希望以后有机会再分享更底层的binder驱动原理吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值