Service功能梳理

        近期公司项目有个Android大屏上的应用开发,外设用到rfid读卡器(usb或者uart接口),为了对外接口简单使用usb和外置读卡器连接。

        驱动移植本着拿来主义直接参考了GitHub上UsbSerial的开源代码,仔细阅读代码发现大神使用的Service来实现,梳理自己应用需求:1、读卡器挂载后自动设置功率;2、多个界面和读卡器进行读写数据交互。受限Android挂载usb设备请求弹窗不好处理,要求usb service不可以在切换界面时stop。按照service的两种通用启动方式来看都不是很好处理。

        这里贴一下service的通用启动方式(复习记录):

        方式1:startService(new Intent(this, UsbService.class));

        方式2:mContext.bindService(new Intent(mContext,UsbService.class),usbConnection,Context.BIND_AUTO_CREATE);

        两种启动方式区别不做详细阐述,可自行查阅资料(本人纯小白)。大致区别:方式1启动service,service生命周期和调用startService函数的Activity没关系,但是方式1启动service和activity交互就不好搞、方式2启动service,service的生命周期和当前activity周期一致(切记bindService和unbindService成对),方式2启动可以通过上诉参数usbConnection获取service实体实现和activity的数据交互。

        梳理到这里就发现和我自己的需求相悖,我要求usb service在后台运行,同时切换界面后可以和usb service实现数据读写交互,如果每次切换界面调用unbindService,service停止后,在新的activity中调用bindService启动service,势必需要会出现新的usb确认弹窗,用户体验很差。

        继续查阅资料,发现service的两种启动方式可以结合使用。结合自己的需求,app启动后首界面直接通过调用方法1启动usb service,在需要和usb service交互的activity的界面可以继续调用方法2来实现usb service的数据交互,这里切记不要忘了unbindService,但是调用unBindService不会干掉service,即可实现我的应用需求。

        继续优化发现,用着还是有点麻烦,每次bind、unbind大量冗余代码,我又将这块代码封装成一个工具类。

public class RfidTool implements HandlerAction, UsbService.OnUsbResponseListener {

    // 上下文

    private Context mContext;

    // service

    protected UsbService mUsbService;

    //读卡状态标志 false:默认状态 true:读卡过程中

    protected boolean mReadCardFlag =false;

    //service和activity连接时间

    private int mBindServiceTime =200;

    //service和activity是否已经连接上

    protected boolean serviceIsBinded =false;

    //activiy用的回调接口

    private RfidToolCallback mRfidToolCallback;

    //超时时间

    private int mTimeout =0;

    //指令

    private List<Byte> mCmd =new ArrayList<>();

    public RfidTool(Context mContext) {

        this.mContext = mContext;

    }

    public Context getContext() {

        return mContext;

    }

    public void setmCmd(List mCmd) {

        this.mCmd = mCmd;

    }

    //绑定

    public RfidTool bindService() {

        if (!UsbService.SERVICE_CONNECTED) {

            Timber.d("start service");

            mContext.startService(new Intent(mContext,PhotoUpdateSerivice.class));

        }

    Intent intent =new Intent(mContext,UsbService.class);

        mContext.bindService(intent,usbConnection,Context.BIND_AUTO_CREATE);

        return this;

    }

    //connection

    private final ServiceConnection usbConnection =new ServiceConnection() {

        @Override

        public void onServiceConnected(ComponentName arg0,IBinder arg1) {

            serviceIsBinded  =true;

            mUsbService = ((UsbService.UsbBinder) arg1).getService();

            mUsbService.setUsbResponseListener(RfidTool.this);

            }

        @Override

        public void onServiceDisconnected(ComponentName arg0) {

            mUsbService =null;

        }

    };

    //开始

    public void start(RfidToolCallback callback){

        mReadCardFlag =true;

        this.mRfidToolCallback = callback;

        if(mRfidToolCallback !=null){

                mRfidToolCallback.onStart();

        }

        //service和activity bind成功需要一定时间

        postDelayed(()->{

            if (mUsbService ==null) {

                failed("USB服务未打开");

                return;

        }

        if(!mUsbService.isSerialPortConnected()){

                mUsbService.findSerialPortDevice();

                failed("未找到读卡器");

                return;

        }

            mUsbService.write(ArrayUtil.listToByte(mCmd));

    } ,mBindServiceTime);

}

    //操作失败(解除绑定、移除回调)

    protected void failed(String message){

        mUsbService.setUsbResponseListener(null);

        removeCallbacks();

        if(serviceIsBinded){

                serviceIsBinded =false;

                mContext.unbindService(usbConnection);

        }

        if(mRfidToolCallback !=null){

                mRfidToolCallback.onFailed(message);

                mRfidToolCallback.onEnd();

            }

    }

//操作成功

    protected void succeed(){

            mUsbService.setUsbResponseListener(null);

            getContext().unbindService(usbConnection);

            removeCallbacks();

            if(mRfidToolCallback !=null){

                    mRfidToolCallback.onSuccess();

                    mRfidToolCallback.onEnd();

            }

        }

    @Override

    public void onDataReceived(byte[] data) {

    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容