此时相当于在客户端和被调用端都有同一份SsoAuth.aidl文件,它们的包名、类名完全一致,生成的SsoAuth.java类也完全一致,这样在远程调用时它们就能够拥有一致的类型。Rebuild被调用端工程之后就会生成SsoAuth.java文件,该文件中有一个Stub类实现了SsoAuth接口。我们首先需要定义一个Service子类,然后再定义一个继承自Stub的子类,并且在Service的onBind函数中返回这个Stub子类的对象。示例代码如下:
public class SinaSsoAuthService extends Service { SinaSsoImpl mBinder = new SinaSsoImpl(); @Override public void onCreate() { super.onCreate(); Log.e("","### sso auth created") ; } @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } // 继承自Stub类,在这里实现ssoAuth函数 class SinaSsoImpl extends SsoAuth.Stub { @Override public void ssoAuth(String userName, String pwd) throws RemoteException { Log.e("", "这里是新浪客户端, 执行SSO登录啦,用户名 : " + userName + ", 密码 : " + pwd) ; } @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } } } |
从上述代码中我们看到,实际上完成功能的是继承自Stub的SinaSsoImpl类,Service只提供了一个让SinaSsoImpl依附的外壳。完成SinaSsoAuthService之后我们需要将它注册在被调用端应用的Manifest中,注册代码如下:
<service android:name=".service.SinaSsoAuthService" android:exported="true" android:process=":remote" android:label="@string/app_name"> <intent-filter> <action android:name="book.aidl_server.service.SinaSsoAuthService"/> </intent-filter> </service> 然后先运行被调用端(也就是Server端)应用,并且在客户端中完成调用Server的代码。客户端Activity的代码如下: public class MainActivity extends AppCompatActivity { SsoAuth mSsoAuth ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 执行操作 findViewById(R.id.sso_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if ( mSsoAuth == null ) { // 绑定远程服务,并且进行登录 bindSsoAuthService(); } else { doSsoAuth(); } } }); } private void bindSsoAuthService() { Intent intent = new Intent("book.aidl_server.service.SinaSsoAuthService") ; bindService(intent, mConnection, Context.BIND_AUTO_CREATE) ; } ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { // 建立连接之后将Binder转换为mSsoAuth mSsoAuth = SsoAuth.Stub.asInterface(iBinder) ; doSsoAuth(); } @Override public void onServiceDisconnected(ComponentName componentName) { mSsoAuth = null; } } ; private void doSsoAuth() { try { // 执行登录,实际上调用的是Server端的ssoAuth函数 mSsoAuth.ssoAuth("Mr.Simple", "pwd123"); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); unbindService(mConnection); } } |
在上述Activity程序中,运行程序后点击登录按钮时会向Server端发起连接Service请求,在建立连接之后会将Binder对象转换为SsoAuth对象,然后调用SsoAuth对象的ssoAuth函数。此时的ssoAuth函数实际上调用的就是Server端中SinaSsoImpl类的实现。运行程序后点击登录按钮,如图1-15所示。
输出结果,如图1-16所示。
▲图1-15 客户端的登录界面▲图1-16 AIDL远程调用
本文选自《Android开发进阶—从小工到专家》第一章,本站经人民邮电出版社和作者的授权。
版权声明:51Testing软件测试网获人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。