AIDL示例

AIDL示例

官方文档

  • 服务端
    • aidl

      IPlayerService.aidl

      package com.example.aidl;
      import com.example.aidl.MusicInfo;
      import com.example.aidl.IMetadataUpdateCallback;
      
      interface IPlayerService {
          MusicInfo getMusicInfo();
          void startPlay();
          void endPlay();
          void registerMetadataUpdateCallback(IMetadataUpdateCallback callback);
          void unregisterMetadataUpdateCallback(IMetadataUpdateCallback callback);
      }
      

      MusicInfo.aidl

      package com.example.aidl;
      
      parcelable MusicInfo;
      

      IMetadataUpdateCallback.aidl

      package com.example.aidl;
      import com.example.aidl.MusicInfo;
      
      interface IMetadataUpdateCallback {
          void onMetadataUpdate(in MusicInfo musicInfo);
      }
      
    • service

      PlayerService.java

      package com.example.aidl;
      
      import android.annotation.TargetApi;
      import android.app.Service;
      import android.content.Intent;
      import android.os.Build;
      import android.os.IBinder;
      import android.os.RemoteCallbackList;
      import android.os.RemoteException;
      import android.util.Log;
      
      /**
       * @author Dongping Wang
       * date 2022/7/14 0:12
       */
      public class PlayerService extends Service {
      
          private static final String TAG = "PlayerService";
      
          private MusicInfo mMusicInfo = new MusicInfo("稻香", "周杰伦");
      
          @Override
          public void onCreate() {
              super.onCreate();
              Log.d(TAG, "onCreate");
          }
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              Log.d(TAG, "onDestroy");
          }
      
          @Override
          public IBinder onBind(Intent intent) {
              Log.d(TAG, "onBind");
              return mBinder;
          }
      
          @Override
          public boolean onUnbind(Intent intent) {
              boolean b = super.onUnbind(intent);
              Log.d(TAG, "onUnbind");
              return b;
          }
      
          @Override
          public void onRebind(Intent intent) {
              super.onRebind(intent);
              Log.d(TAG, "onRebind");
          }
      
          private IBinder mBinder = new IPlayerService.Stub() {
      
              private RemoteCallbackList<IMetadataUpdateCallback> callbacks = new RemoteCallbackList<IMetadataUpdateCallback>() {
                  @Override
                  public void onCallbackDied(IMetadataUpdateCallback callback) {
                      super.onCallbackDied(callback);
                      Log.d(TAG, "onCallbackDied:" + callback);
                  }
              };
      
              @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
              private void notifyMetadataUpdated() {
                  callbacks.beginBroadcast();
                  for (int i = 0; i < callbacks.getRegisteredCallbackCount(); i++) {
                      try {
                          callbacks.getBroadcastItem(i).onMetadataUpdate(mMusicInfo);
                      } catch (RemoteException e) {
                          e.printStackTrace();
                      }
                  }
                  callbacks.finishBroadcast();
              }
      
              @Override
              public MusicInfo getMusicInfo() throws RemoteException {
                  Log.d(TAG, "getMusicInfo: " + mMusicInfo.toString());
                  return mMusicInfo;
              }
      
              @Override
              public void startPlay() throws RemoteException {
                  Log.d(TAG, "startPlay");
                  // fixme:模拟当前歌曲变化,测试用
                  notifyMetadataUpdated();
              }
      
              @Override
              public void endPlay() throws RemoteException {
                  Log.d(TAG, "endPlay");
              }
      
              @Override
              public void registerMetadataUpdateCallback(IMetadataUpdateCallback callback) throws RemoteException {
                  Log.d(TAG, "registerMetadataUpdateCallback:" + callback);
                  callbacks.register(callback);
              }
      
              @Override
              public void unregisterMetadataUpdateCallback(IMetadataUpdateCallback callback) throws RemoteException {
                  Log.d(TAG, "unregisterMetadataUpdateCallback:" + callback);
                  callbacks.unregister(callback);
              }
          };
      }
      

      服务在AndroidManifest中配置,指定:Remote进程

      <service
                  android:name=".PlayerService"
                  android:enabled="true"
                  android:exported="true"
                  android:process=":Remote">
                  <intent-filter>
                      <action android:name="example.intent.action.TEST_AIDL" />
                  </intent-filter>
      </service>
      

      MusicInfo.java

      package com.example.aidl;
      
      import android.os.Parcel;
      import android.os.Parcelable;
      
      /**
       * @author Dongping Wang
       * date 2022/7/14 0:18
       */
      public class MusicInfo implements Parcelable {
      
          private String title;
          private String singer;
      
          public MusicInfo() {
          }
      
          public MusicInfo(String title, String singer) {
              this.title = title;
              this.singer = singer;
          }
      
          protected MusicInfo(Parcel in) {
              title = in.readString();
              singer = in.readString();
          }
      
          public static final Creator<MusicInfo> CREATOR = new Creator<MusicInfo>() {
              @Override
              public MusicInfo createFromParcel(Parcel in) {
                  return new MusicInfo(in);
              }
      
              @Override
              public MusicInfo[] newArray(int size) {
                  return new MusicInfo[size];
              }
          };
      
          public String getTitle() {
              return title;
          }
      
          public void setTitle(String title) {
              this.title = title;
          }
      
          public String getSinger() {
              return singer;
          }
      
          public void setSinger(String singer) {
              this.singer = singer;
          }
      
          @Override
          public String toString() {
              return "MusicInfo{" +
                      "title='" + title + '\'' +
                      ", singer='" + singer + '\'' +
                      '}';
          }
      
          @Override
          public int describeContents() {
              return 0;
          }
      
          @Override
          public void writeToParcel(Parcel dest, int flags) {
              dest.writeString(title);
              dest.writeString(singer);
          }
      }
      
  • 客户端

    通过PlayerServiceManager 进行调用服务端代码

    package com.example.aidl;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    /**
     * @author Dongping Wang
     * date 2022/7/14 22:04
     */
    public final class PlayerServiceManager {
    
        private static final String ACTION_PLAYER_SERVICE = "example.intent.action.TEST_AIDL";
        private static final String PACKAGE_PLAYER_SERVICE = "com.example.aidl";
    
        private static final String TAG = "PlayerServiceManager";
    
        private Context mContext;
        private ServiceConnection mServiceConn;
        private volatile boolean mServiceRegistered;
        private IPlayerService playerService;
        private List<PlayerServiceConnectionListener> listeners = new CopyOnWriteArrayList<>();
    
        public static PlayerServiceManager newInstance(Context context) {
            return new PlayerServiceManager(context);
        }
    
        private PlayerServiceManager(Context context) {
            this.mContext = context;
        }
    
        public boolean bindService() {
            if (mServiceRegistered) {
                return true;
            }
            mServiceConn = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, final IBinder service) {
                    Log.d(TAG, "onServiceConnected");
                    playerService = IPlayerService.Stub.asInterface(service);
                    for (PlayerServiceConnectionListener listener : listeners) {
                        listener.onServiceConnected();
                    }
                    try {
                        service.linkToDeath(new IBinder.DeathRecipient() {
                            @Override
                            public void binderDied() {
                                Log.d(TAG, "binderDied");
                                service.unlinkToDeath(this, 0);
                                bindService();
                            }
                        }, 0);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onServiceDisconnected(ComponentName name) {
                    Log.d(TAG, "onServiceDisconnected");
                    for (PlayerServiceConnectionListener listener : listeners) {
                        listener.onServiceDisconnected();
                    }
                    playerService = null;
                }
            };
            Intent intent = new Intent().setAction(ACTION_PLAYER_SERVICE).setPackage(PACKAGE_PLAYER_SERVICE);
            mServiceRegistered = mContext.bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
            return mServiceRegistered;
        }
    
        public boolean unbindService() {
            if (!mServiceRegistered) {
                return false;
            }
            if (mServiceConn != null) {
                mContext.unbindService(mServiceConn);
                mServiceRegistered = false;
                return true;
            }
            return false;
        }
    
        public void startPlay() {
            if (playerService != null) {
                try {
                    playerService.startPlay();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void endPlay() {
            if (playerService != null) {
                try {
                    playerService.endPlay();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public MusicInfo getMusicInfo() {
            if (playerService != null) {
                try {
                    return playerService.getMusicInfo();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        public void registerMetadataUpdateCallback(IMetadataUpdateCallback callback) {
            if (playerService != null) {
                try {
                    playerService.registerMetadataUpdateCallback(callback);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void unregisterMetadataUpdateCallback(IMetadataUpdateCallback callback) {
            if (playerService != null) {
                try {
                    playerService.unregisterMetadataUpdateCallback(callback);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void registerPlayerServiceConnectionListener(PlayerServiceConnectionListener listener) {
            if (!listeners.contains(listener)) {
                listeners.add(listener);
            }
        }
    
        public void unregisterPlayerServiceConnectionListener(PlayerServiceConnectionListener listener) {
            if (listeners.contains(listener)) {
                listeners.remove(listener);
            }
        }
    
        public interface PlayerServiceConnectionListener {
            void onServiceConnected();
    
            void onServiceDisconnected();
        }
    }
    

    MainActivity中四个按按钮来绑定、解绑、调用

    package com.example.aidl;
    
    import android.os.Bundle;
    import android.os.RemoteException;
    import android.util.Log;
    import android.view.View;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
        private PlayerServiceManager playerService = PlayerServiceManager.newInstance(this);
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void bindService(View view) {
            playerService.bindService();
            playerService.registerPlayerServiceConnectionListener(listener);
        }
    
        public void unbindService(View view) {
            playerService.unregisterMetadataUpdateCallback(callback);
            playerService.unbindService();
        }
    
        public void startPlay(View view) {
            playerService.startPlay();
        }
    
        public void endPlay(View view) {
            playerService.endPlay();
        }
    
        private final IMetadataUpdateCallback callback = new IMetadataUpdateCallback.Stub() {
            @Override
            public void onMetadataUpdate(MusicInfo musicInfo) throws RemoteException {
                Log.d(TAG, "onMetadataUpdate:" + musicInfo.toString());
            }
        };
    
        private final PlayerServiceManager.PlayerServiceConnectionListener listener = new PlayerServiceManager.PlayerServiceConnectionListener() {
            @Override
            public void onServiceConnected() {
                playerService.registerMetadataUpdateCallback(callback);
            }
    
            @Override
            public void onServiceDisconnected() { }
        };
    }
    

    输出结果:

    2022-07-16 12:44:42.100 1874-1903/system_process I/ActivityManager: Start proc 9341:com.example.aidl:Remote/u0a133 for service {com.example.aidl/com.example.aidl.PlayerService}
    2022-07-16 12:44:42.266 9341-9341/? D/PlayerService: onCreate
    2022-07-16 12:44:42.266 9341-9341/? D/PlayerService: onBind
    2022-07-16 12:44:42.267 9307-9307/com.example.aidl D/PlayerServiceManager: onServiceConnected
    2022-07-16 12:44:42.269 9341-9361/? D/PlayerService: registerMetadataUpdateCallback:com.example.aidl.IMetadataUpdateCallback$Stub$Proxy@4a38442
    2022-07-16 12:44:44.959 9341-9361/? D/PlayerService: startPlay
    2022-07-16 12:44:44.961 9307-9307/com.example.aidl D/MainActivity: onMetadataUpdate:MusicInfo{title='稻香', singer='周杰伦'}
    2022-07-16 12:44:47.278 9341-9361/? D/PlayerService: unregisterMetadataUpdateCallback:com.example.aidl.IMetadataUpdateCallback$Stub$Proxy@e410990
    2022-07-16 12:44:47.281 9341-9341/? D/PlayerService: onUnbind
    2022-07-16 12:44:47.281 9341-9341/? D/PlayerService: onDestroy
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值