Android aidl简单使用2

Android  2023年8月28日 am8:08发布1年前 (2023)更新 91es.com站长
87 0 0

前言

之前记录AndroidAIDL使用,这次就多个进程绑定同一个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中。

参考文章

  1. Android aidl简单使用

 历史上的今天

  1. 2020: Android动画之TranslateAnimation使用(0条评论)
  2. 2019: 林清玄:把时间花在心灵上(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

张悦然:旧时光是个美人

我们向前走了很远,才回头。我们追溯的时候,就为她画眉。她的眉太淡,面容太模糊,如何敌得过岁月稀释,情爱挥发。有一段梦游:我们逆走来时路,转几个风口,终于聚在往事的老宅。 于是我们给她画眉,旧时光是个美人。将眉毛一遍遍描黑,但除此之外,我们不能做什么,不能修补她惨淡的微...

[摘]Android稳定性(一)SWT和ANR

前言查找SWT啥意思时找到这篇文章,加上项目中用的也是MTK平台,因此摘抄这篇文章于此,方便自己学习和查阅。本文摘抄,感谢作者分析。好记性不如烂笔头正文SWT这里解释了什么是SWT以及SWT的作用。什么是SWTSWT:software watchdog,监控SystemServer进...

徐志摩 :偶然

我是天空里的一片云,偶尔投影在你的波心──你不必讶异,更无须欢喜──在转瞬间消灭了踪影。 你我相逢在黑夜的海上,你有你的,我有我的,方向;你记得也好,最好你忘掉在这交会时互放的光亮!

[摘]Android稳定性(二)bootup fail

前言之前我也有整理相关的,但没有摘抄的这篇文章那么详细,因此这里摘抄于此,方便自己查阅。本文摘抄,感谢作者分析。好记性不如烂笔头正文下面就简单介绍一下Android系统启动流程。BootLoader启动开机供电,硬件电路会产生一个确定的复位时序用于硬件启动顺序,直至最后CPU启动;C...

三毛:胆小鬼

这件事情,说起来是十分平淡的。也问过好几个朋友,问他们有没有同样的经验,多半答说有的,而结果却都相当辉煌,大半没有捱打也没有被责备。我要说的是——偷钱。当然,不敢在家外面做这样的事情,大半是翻父母的皮包或口袋,拿了一张钞票。朋友们在少年的时候,偷了钱大半请班上同学吃东西,快快花光,回去再受罚。...

史铁生:想念地坛

想念地坛,主要是想念它的安静。坐在那园子里,坐在不管它的哪一个角落,任何地方,喧嚣都在远处。近旁只有荒藤老树,只有栖居了鸟儿的废殿颓檐、长满了野草的残墙断壁,暮鸦吵闹着归来,雨燕盘桓吟唱,风过檐铃,雨落空林,蜂飞蝶舞草动虫鸣……四季的歌咏此起彼伏从不间断。地坛的安静并非无声。有一天大雾迷漫,世界...