美文网首页
Android使用多进程来进行串口读写

Android使用多进程来进行串口读写

作者: GiftedCat | 来源:发表于2020-06-13 13:45 被阅读0次

一、前言

前段时间在工作中有一个棘手的问题,接手了一个Android项目,因需要投入使用的设备内存小(RAM1GB)且使用到串口较多,频次较高的原因,在某些页面使用上会出现略微的卡顿,导致用户体验不是特别好,我当时的想法是:如果把1GB换成2GB,那么这把牌将绝杀,可惜设备已经订好了,换不得。

初步决定使用多线程的方式,将串口读写的工作和业务代码分开来,一个是把代码模块化,另外一个是多进程便可以从系统处分配出更多的内存以加快整个APP的响应速度。

二、原理图

先贴一下整个流程的原理图

image

原理比较清晰,由Service和串口进程通信,我们的Application与Service进行绑定,通过Messenger和Service进行交互,而数据由Application通过Eventbus进行下发给页面

三、实现功能

(一)Service和串口通信

我这边开了两个串口做演示,一个是ttyS0,波特率9600
另外一个是ttyS1,波特率9600

        mSerialPortManager1 = new SerialPortManager(new File("/dev/ttyS0"), 9600)
                .setOnSerialPortDataListener(new OnSerialPortDataListener() {
                    @Override
                    public void onDataReceived(byte[] bytes) {
                        /** 接收到串口数据*/
                        sendMessageToClient(101, new String(bytes));
                    }
                });
        mSerialPortManager2 = new SerialPortManager(new File("/dev/ttyS1"), 9600)
                .setOnSerialPortDataListener(new OnSerialPortDataListener() {
                    @Override
                    public void onDataReceived(byte[] bytes) {
                        sendMessageToClient(102, new String(bytes));
                    }
                });

(二)Service和Application的交互

Service和Application属于不同的进程,所以涉及到跨进程通信
我使用的是Messenger,可参考https://www.jianshu.com/p/671b07f5ef86
当然跨进程的方式有很多,我这边选了一个比较简单的来使用
感兴趣的同学可以自行深挖,此处不展开篇幅谈多进程

因为实际使用如我这个项目中用了n多的指令和串口,所以我使用Message的what作为状态码code来区分不同的指令
这是service中接收数据的Handler
200是接收到application传递过来的Messenger,用于初始化
201和202都是从主进程发过来的数据,用于两个串口

    @SuppressLint("HandlerLeak")
    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            switch (msg.what) {
                /** 初始化成功*/
                case 200:
                    Message message = Message.obtain(null, 100, 1, 1);
                    bundle.putString("key", "client create success");
                    message.setData(bundle);
                    mClient = msg.replyTo;
                    try {
                        mClient.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                case 201:
                    /** 接收到用户端需要发送数据指令201*/
                    boolean sendBytes = mSerialPortManager1.sendTxt(bundle.get("data").toString());
                    Log.i(TAG, "onSend: sendBytes = " + sendBytes);
                    Log.i(TAG, sendBytes ? "发送成功" : "发送失败");
                    break;
                case 202:
                    /** 接收到用户端需要发送数据指令202*/
                    mSerialPortManager2.sendTxt(bundle.get("data").toString());
                    break;
                default:
                    break;
            }
        }
    }

这是Application中的Handler
数据来源于串口的数据回调

        serialHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                Bundle bundle = msg.getData();
                switch (msg.what) {
                    case 100:
                        /** 初始化时返回的数据*/
                        Log.i(TAG, "接收到Service发送的数据");
                        break;
                    case 101:
                        /** 接收101数据*/
                        EventBus.getDefault().post(new SerialDataEvent(msg.what, bundle.get("data").toString()));
                        break;
                    case 102:
                        /** 接收到102数据*/
                        EventBus.getDefault().post(new SerialDataEvent(msg.what, bundle.get("data").toString()));
                        break;
                    default:
                        break;
                }
            }
        };

(三)Application下发数据和接收数据

数据下发就由EventBus来完成了,非常好用
而页面需要向串口传数据我在Application中创建了一个全局的Messenger
mServer,在绑定Service的时候将其初始化,便可以使用

        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.i(TAG, "onServiceConnected: ComponentName = " + name);
                mServer = new Messenger(service);
                Log.i(TAG, "连接成功...................");
                Message message = Message.obtain(null, 200);
                message.replyTo = mClient;
                try {
                    mServer.send(message);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };

发送数据的代码

    /**
     * 发送数据至Service
     * */
    public static void sendMessageToServer(int code, String data) {
        Message message = Message.obtain(null, code);
        Bundle bundle = new Bundle();
        bundle.putString("data", data);
        message.setData(bundle);
        try {
            InitApplication.mServer.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

四、总结

比起直接使用串口多了几个步骤,便可以实现多进程的串口读写了
不仅运行速度有了明显的提高,而且可以全局的读写串口数据,并不是以前单一的页面使用串口,也不需要频繁的开关串口,如果有多个页面需要用到串口,也不用重复的写无意义的代码,可谓是一举多得

有问题和建议都可以在评论区给我留言

源码地址:https://github.com/Giftedcat/AndroidSerialPortManager

相关文章

  • Android使用多进程来进行串口读写

    一、前言 前段时间在工作中有一个棘手的问题,接手了一个Android项目,因需要投入使用的设备内存小(RAM1GB...

  • ROS用python读写串口数据

    程序: 流程: 首先在Ubuntu下安装pyserial 查看串口名称,并给予权限 进行读写实验 在读写使用中用s...

  • 【串口通信】OK_3568主板串口无法正常初始化问题解决

    问题背景 需要基于OK_3568开发板(Android 11)进行串口通信开发调试,使用Google自带的串口工具...

  • 串口通信

    关于android单片机串口通信 网上有很多关于android串口读写的结果,但是搜出来的都不太让我满意 ,下面贴...

  • [097] 技术-java中的读写锁

    读写所概念 我们平常通过锁来对进程进行协同。但如果在读多写少的场景(可以允许多个读同时进行不影响)也使用普通的锁,...

  • Android串口通信:串口读写

    在不久前,接触到了物联网的开发,当时一脸懵逼了,后来问了度娘和有幸遇到大神的指导,最终实现了功能。 首先先弄懂跟硬...

  • 使用socat虚拟串口

    1、下载socat 2、虚拟串口 3、使用串口 根据步骤2创建的串口名称链接串口、2步骤进程需一直开启

  • Android串口通讯

    简介 在Android上使用串口通讯一般就是用google官方的串口demo代码(android-serialpo...

  • Android IOT 串口&USB

    外设 使用串口 使用USB设备 开源工程 android-serialport-api android-seria...

  • Android 多进程通信之几个基本问题

    Android多进程系列 Android多进程之Binder的使用 开启多进程的方法 Android 中使用多进程...

网友评论

      本文标题:Android使用多进程来进行串口读写

      本文链接:https://www.haomeiwen.com/subject/tfbatktx.html