zoukankan      html  css  js  c++  java
  • AIDL(2):服务端回调客户端

    1.大致流程

    • 在服务端声明远程服务接口IRemoteService.aidl,并声明回调接口ICallback.aidl
    • 在服务端实现远程服务接口IRemoteService.Stub
    • 使用RemoteCallbackList保存回调接口列表
    • 发布服务
    • 在客户端实现回调接口 ICallback.Stub
    • 绑定服务,注册回调接口
    • 调用服务
    • 远程服务从RemoteCallbackList中找到回调,然后调用.

    2.服务端

    2.1 声明服务接口IRemoteService.aidl

     1 // IRemoteService.aidl
     2 package com.example.ee.aidl;
     3 
     4 import com.example.ee.aidl.ICallback;
     5 
     6 interface IRemoteService {
     7 
     8     int getPid();
     9     oneway void fun1();
    10     void registerCallback(ICallback cb);
    11     void unregisterCallback(ICallback cb);
    12 }

    2.2 声明回调接口ICallback.aidl

    1 // ICallback.aidl
    2 package com.example.ee.aidl;
    3 
    4 
    5 interface ICallback {
    6     oneway void fun2();
    7 }

    2.3 实现服务,用 RemoteCallbackList 保存回调接口.

     1 package com.example.ee.aidl;
     2 
     3 import android.app.Service;
     4 import android.content.Intent;
     5 import android.os.IBinder;
     6 import android.os.Process;
     7 import android.os.RemoteCallbackList;
     8 import android.os.RemoteException;
     9 import android.support.annotation.Nullable;
    10 import android.util.Log;
    11 
    12 public class RemoteService extends Service {
    13     final String TAG = "RemoteService";
    14 
    15     private RemoteBinder binder = new RemoteBinder();
    16     private RemoteCallbackList<ICallback>  callbackList = new RemoteCallbackList<>();
    17 
    18     @Nullable
    19     @Override
    20     public IBinder onBind(Intent intent) {
    21         return binder;
    22     }
    23 
    24     class RemoteBinder extends IRemoteService.Stub{
    25 
    26         void callback(){
    27             int count = callbackList.beginBroadcast();
    28             try {
    29                 for (int i = 0; i < count; i++) {
    30                     callbackList.getBroadcastItem(i).fun2();
    31                 }
    32             } catch (RemoteException e) {
    33                 Log.e(TAG, e.getMessage());
    34             } finally {
    35             }
    36             callbackList.finishBroadcast();
    37         }
    38 
    39 
    40         @Override
    41         public int getPid() throws RemoteException {
    42             return Process.myPid();
    43         }
    44 
    45         @Override
    46         public void fun1() throws RemoteException {
    47             Log.d(TAG, "fun1 in remote service ");
    48             callback();
    49         }
    50 
    51         @Override
    52         public void registerCallback(ICallback cb) throws RemoteException {
    53             callbackList.register(cb);
    54         }
    55 
    56         @Override
    57         public void unregisterCallback(ICallback cb) throws RemoteException {
    58             callbackList.unregister(cb);
    59         }
    60     }
    61 }

    2.4 发布服务

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.ee.aidl">
     4 
     5     <application
     6         android:allowBackup="false"
     7         android:icon="@mipmap/ic_launcher"
     8         android:label="@string/app_name"
     9         android:roundIcon="@mipmap/ic_launcher_round"
    10         android:supportsRtl="true"
    11         android:name=".AidlApp"
    12         android:theme="@style/AppTheme">
    13         <!--<meta-data
    14             android:name="APP_CHANNEL"
    15             android:value="${APP_CHANNEL}" />
    16 -->
    17         <activity android:name=".MainActivity">
    18             <intent-filter>
    19                 <action android:name="android.intent.action.MAIN" />
    20 
    21                 <category android:name="android.intent.category.LAUNCHER" />
    22             </intent-filter>
    23         </activity>
    24         <service android:name=".RemoteService" android:process=".RemoteService" android:exported="true"/>
    25     </application>
    26 
    27 </manifest>

    3.客户端

    3.1 实现回调接口

    1     private ICallback callback  = new ICallback.Stub(){
    2 
    3         @Override
    4         public void fun2() throws RemoteException {
    5             Log.d(TAG, "fun2 in client ");
    6         }
    7     };

    3.2 绑定远程服务,注册回调

     1     private void bindRemoteService(){
     2         connection = new ServiceConnection() {
     3             @Override
     4             public void onServiceConnected(ComponentName name, IBinder service) {
     5                 remoteService = IRemoteService.Stub.asInterface(service);
     6                 try {
     7                     remoteService.registerCallback(callback);
     8                 } catch (RemoteException e) {
     9                     e.printStackTrace();
    10                 }
    11             }
    12 
    13             @Override
    14             public void onServiceDisconnected(ComponentName name) {
    15 
    16             }
    17         };
    18 
    19         Intent intent = new Intent(this,RemoteService.class);
    20         boolean ret = bindService(intent,connection, BIND_AUTO_CREATE);
    21         if (!ret ){
    22             Log.e(TAG, "bindRemoteService: bind failed.");
    23         }
    24     }

    3.3 调用远程服务

     1     public void onClick(View view){
     2         if(view.getId() == R.id.btn_call_remote){
     3             AidlApp app = (AidlApp) getApplication();
     4             if (app.remoteService != null){
     5                 try {
     6                     int pid = app.remoteService.getPid();
     7                     Log.d(TAG, "onServiceConnected: remote pid = " + pid);
     8                     app.remoteService.fun1();
     9                 } catch (RemoteException e) {
    10                     e.printStackTrace();
    11                 }
    12             }else {
    13                 Snackbar.make(view,"remote service unbinded",Snackbar.LENGTH_SHORT).show();
    14             }
    15         }
    16     }

    4. 远程服务调用回调

     1     void callback(){
     2             int count = callbackList.beginBroadcast();
     3             try {
     4                 for (int i = 0; i < count; i++) {
     5                     callbackList.getBroadcastItem(i).fun2();
     6                 }
     7             } catch (RemoteException e) {
     8                 Log.e(TAG, e.getMessage());
     9             } finally {
    10             }
    11             callbackList.finishBroadcast();
    12     }

     5.下载

      https://gitee.com/xi/RemoteCallbackList.git

  • 相关阅读:
    发现一个github上特别优秀的面试准备资料
    坠吼的大哥的博客
    [BJDCTF 2nd]假猪套天下第一
    [网鼎杯 2020 朱雀组]phpweb
    [GWCTF 2019]我有一个数据库
    [BJDCTF2020]ZJCTF,不过如此
    [GXYCTF2019]禁止套娃
    洛谷
    [ZJCTF 2019]NiZhuanSiWei
    蓝帽杯决赛-爆炒腰花-WP
  • 原文地址:https://www.cnblogs.com/mhbs/p/7645525.html
Copyright © 2011-2022 走看看