栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android跨进程通信(二):AIDL使用教程2

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android跨进程通信(二):AIDL使用教程2

上一篇文章讲述如何编写服务端的代码,本篇文章讲解客户端代码的编写,并测试两程序的进程间通信。

编写客户端的AIDL代码

上篇文章也说过AIDL对包名要求很苛刻,因此在编写的时候要格外注意。

首先,切换为Project模式。

在main文件夹上创建一个新文件夹,一定要叫aidl。

按照下面这种方式创建一个aidl文件,然后不管它(这是为了解决Android Studio的一个"小"bug),这个步骤不能漏。

接着把服务端的aidl包一整个复制到客户端的aidl下。

复制后,客户端的aidl文件夹如下,注意此时的sensorapp文件夹是无效的,因为这个包名并不是完整的包名(这就是Android Studio的bug),完整的包名是com.pyjtlk.sensorapp,也就是服务端aidl文件的包名。

于是再在aidl下创建com.pyjtlk.sensorapp包,并把sensorapp的aidl文件复制进去,最终正确的结果如下。

把上面红色的零时包删掉,最后就在客户端上得到完整服务端包名的aidl。

通过同样的方法把服务端的SensorConfig.java文件也复制到客户端的java文件夹上(注意包名!)

至此,客户端的AIDL才算完成。先clean一下工程,再rebuild,如果没有错误提示,并生成对应的接口文件,那才算是真正的成功。

如果不成功,那就得仔细地核对服务端和客户端的aidl代码是否一致,通常是AIDL包名不一致导致错误的。

编写客户端Activity代码

相比于AIDL,java和xml就简单多了,先来看界面代码。很简单,就是一个文本框和三个按钮。




    

    

再来看看Activity的代码。在onServiceConnected方法中,客户端就能获取到服务端的Binder对象。

public class MainActivity extends AppCompatActivity {
    private TextView mTempText;
    private Button mGetButton;
    private Button mOpenButton;
    private Button mShutButton;

    private SensorServiceConnection mServiceConnection;
    private ISensorAidlInterface mSensorAidlInterface;

    private class SensorServiceConnection implements ServiceConnection{
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //得到来自服务端的Binder
            mSensorAidlInterface = ISensorAidlInterface.Stub.asInterface(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        bindService();
    }

    private void initView(){
        mTempText = findViewById(R.id.text_temp);
        mGetButton = findViewById(R.id.button_getTemp);
        mOpenButton = findViewById(R.id.button_open);
        mShutButton = findViewById(R.id.button_shut);

        mGetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    //跨进程通信,获取服务端的传感器温度值
                    double temperature = mSensorAidlInterface.getTemperature();
                    mTempText.setText(temperature + "℃");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

        mOpenButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    SensorConfig sensorConfig = new SensorConfig();
                    sensorConfig.setSensorName("TI Temperature Sensor");
                    sensorConfig.setCmd("open temperature sensor");
                    //跨进程发送对象
                    mSensorAidlInterface.setSensor(sensorConfig);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

        mShutButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    SensorConfig sensorConfig = new SensorConfig();
                    sensorConfig.setSensorName("TI Temperature Sensor");
                    sensorConfig.setCmd("shut temperature sensor");
                    //跨进程发送对象
                    mSensorAidlInterface.setSensor(sensorConfig);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void bindService(){
    	//这是隐式启动Service的方法,Android5.0开始就不支持了
		//Intent intent = new Intent("com.pyjtlk.sensorapp.SensorService"); 
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.pyjtlk.sensorapp","com.pyjtlk.sensorapp.SensorService"));

        mServiceConnection = new SensorServiceConnection();
		
        bindService(intent,mServiceConnection,BIND_AUTO_CREATE);
    }
}

终于写完了服务端和客户端的代码,接下来就进行测试。

测试

首先,通过debug模式启动服务端,不要退出。再启动客户端应用。

点击第一个按钮,客户端就获取到了服务端的温度值。

两个应用真的跨进程通信了吗?下面来做第二个测试。

打开服务端的代码在SensorService.java的setSensor方法上设一个断点。然后点击客户端App的第二个按钮。

如下图,服务端断点被拦截,说明客户端跨进程发送的对象确实被服务端收到了。

最后

服务端和客户端都放在Gitee代码仓库里了。

下一篇文章我们来看看如何使用Messenger来实现跨进程通信。对AIDL原理感兴趣的朋友可以看看这篇文章。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/720848.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号