目录
前言
之前记录Android的AIDL使用,这次就多个进程绑定同一个AIDL服务,其实跟之前一样,只不过是进行了多次绑定而已。
流水账,可以不用看
正文
存在如下模块和lib库
# lib库 BiuMoreAidl # 模块(客户端和服务端) BiuMoreAidlClent BiuMoreAidlService
客户端里两个Activity,但不同进程。
BiuMoreAidl
lib库中就公用的aidl的定义
// IMedia.aidl package com.biumall.aidl; interface IMedia { void previous(); void play(); void pause(); void next(); }
build.gradle中添加
buildFeatures{aidl true}
BiuMoreAidlService
这里需要引入BiuMoreAidl
startService(new Intent(this, AidlService.class));
build.gradle
dependencies { implementation project(":BiuMoreAidl") }
AndroidManifest.xml
这里是服务配置,配置了一个Action,方便用于启动服务。
<service android:name=".AidlService" android:exported="true"> <intent-filter> <action android:name="com.biumall.service.AidlService" /> </intent-filter> </service>
ServiceApp.java
这里开启服务
public class ServiceApp extends Application { @Override public void onCreate() { super.onCreate(); startService(new Intent(this, AidlService.class)); } }
MediaBinder.java
MediaBinder是实现IMedia.aidl接口
public class MediaBinder extends IMedia.Stub { private int mCount = 0; public void onStart() { } public void onStop() { } @Override public void previous() throws RemoteException { } @Override public void play() throws RemoteException { } @Override public void pause() throws RemoteException { mCount++; //每次调用增加异常 } @Override public void next() throws RemoteException { } }
除了实现IMedia.aidl接口,还是薪资两个方法onStart()和onStop(),用于初始化和关闭资源,这里暂时不做啥、
AidlService.java
后台服务,用于被客户端绑定,并返回MediaBinder的。
public class AidlService extends Service { private MediaBinder mMediaBinder; @Nullable @Override public IBinder onBind(Intent intent) { return mMediaBinder; } @Override public void onCreate() { super.onCreate(); mMediaBinder = new MediaBinder(); mMediaBinder.onStart(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); if (null != mMediaBinder) { mMediaBinder.onStop(); } mMediaBinder = null; } }
BiuMoreAidlClent
客户端就分两个Activity不同进程中进行绑定服务。
build.gradle
也需要引入BiuMoreAidl
dependencies { implementation project(":BiuMoreAidl") }
AndroidManifest.xml
<activity android:name="com.biumall.client.MainActivity" android:exported="true" android:launchMode="singleInstance"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.biumall.client.TwoActivity" android:exported="true" android:launchMode="singleInstance" android:process=":another_process"> </activity>
android:process=":another_process"这可以说可以开启新的进程。
ClientApp.java
public class ClientApp extends Application { @SuppressLint("StaticFieldLeak") private static Context mContext = null; @Override public void onCreate() { super.onCreate(); mContext = this; } public static Context getContext() { return mContext; } }
MainActivity.java
PS: TwoActivity跟MainActivity一样,这里就不附上了
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private IMedia mIMedia; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); bindService(); } @Override protected void onDestroy() { super.onDestroy(); unbindService(); } private void bindService() { if (null == mIMedia) { Intent intent = new Intent(); //需要指定绑定包名,不可以匿名绑定服务 intent.setPackage("com.biumall.service"); intent.setAction("com.biumall.service.AidlService"); boolean bind = ClientApp.getContext().bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } } private void unbindService() { if (null != mIMedia) { ClientApp.getContext().unbindService(mServiceConnection); mIMedia = null; } } private void initUI() { findViewById(R.id.main_bt_go_other).setOnClickListener(this); findViewById(R.id.main_bt_pause).setOnClickListener(this); findViewById(R.id.main_bt_play).setOnClickListener(this); findViewById(R.id.main_bt_previous).setOnClickListener(this); findViewById(R.id.main_bt_next).setOnClickListener(this); } private final ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMedia = IMedia.Stub.asInterface(service); try { mIMedia.asBinder().linkToDeath(new IBinder.DeathRecipient() { @Override public void binderDied() { //binderDied } }, 0); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mIMedia = null; } }; @SuppressLint("NonConstantResourceId") @Override public void onClick(View v) { try { switch (v.getId()) { case R.id.main_bt_go_other: Intent intent = new Intent(MainActivity.this, TwoActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ClientApp.getContext().startActivity(intent); break; case R.id.main_bt_previous: if (null != mIMedia) { mIMedia.previous(); } break; case R.id.main_bt_next: if (null != mIMedia) { mIMedia.next(); } break; case R.id.main_bt_pause: if (null != mIMedia) { mIMedia.pause(); } break; case R.id.main_bt_play: if (null != mIMedia) { mIMedia.play(); } break; } } catch (Exception e) { e.printStackTrace(); } } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/background_dark" android:gravity="center" android:orientation="vertical"> <Button android:id="@+id/main_bt_go_other" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="GoTo Two" android:textSize="30sp" /> <Button android:id="@+id/main_bt_play" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="Play" android:textSize="30sp" /> <Button android:id="@+id/main_bt_pause" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="Pause" android:textSize="30sp" /> <Button android:id="@+id/main_bt_previous" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="Previous" android:textSize="30sp" /> <Button android:id="@+id/main_bt_next" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="Next" android:textSize="30sp" /> </LinearLayout>
小结
同一个服务,可以被多次绑定,然后真正功能实现者在MediaBinder中。
参考文章
-
《
历史上的今天
暂无评论...
随机推荐
WordPress博客搬家教程
这是建站的必备知识,我们需要怎么进行网络搬家,如果你不会,请仔细研读。这一篇文章写得最简单最明白的。第一步:备份网站根目录下所有文件并转移到新主机。这一步主要是把原来的空间中的网站程序、图片等资源下载备份,并上传到新的主机空间。如果原来空间支持在线压缩,并且新的空间支持解压缩,那么建议...
Kotlin字符串
前言简单记录一下Kotlin字符串。主要是方便自己查阅。正文字符串一个字符串可以包含一个或者多个字符,也可以不包含任何字符,即长度为0。var mString: String = "谷歌一下"var mString2 = "百度一下"遍历字符串遍历也是很多种,下面列举验证过的遍历...
顾城:门前
我多么希望,有一个门口早晨,阳光照在草上 我们站着扶着自己的门扇门很低,但太阳是明亮的 草在结它的种子风在摇它的叶子我们站着,不说话就十分美好 有门,不用开开是我们的,就十分美好
ThreadPoolExecutor简单记录
前言线程经常用,线程池也用,但在于如何使用,没有记录一下。本文参考别人文章整理。正文使用线程池的好处降低内存资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。在线程池中的线程都是已经被创建好的,我们的任务直接获取一个空闲的线程就能够被执行了提高线程的可管...
莫言:陪女儿高考
那天晚上,带着书、衣服、药品、食物等诸多在这三天里有可能用得着的东西,搭出租车去赶考。我们很运气,女儿的考场排在本校,而且提前在校内培训中心定了一个有空调的房间,这样既是熟悉的环境,又免除了来回奔波之苦。信佛的妻子说这是佛祖的保佑啊!我也说,是的,这是佛祖的保佑。坐在出租车上,看到车牌照上的号码尾...
MediaPlayer java层介绍
前言Android中经常用MediaPlayer控制音频/视频文件和流的播放。虽然经常用,但没怎么看其源码,今天有空记录一下,方便自己查阅。正文本篇涉及的源码目录frameworks\base\media\java\android\media\MediaPlayer.javaPS:只是...