导航号,我的单页导航
文章目录

前言

之前记录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();
}

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简单使用

© 版权声明
导航号,我的单页导航

暂无评论

暂无评论...