昨天天算法组同事给我了两个新so文件,给我说速度提升好几倍,心想更换so文件,提示识别效率,心里就美滋滋的。
等我拿到so文件替换 运行后才发现,so底层库报错了,查找了好久,最后定位错误是Android端 运行这两个so文件时不能在同一进程中,也就是说需要开启多进程。
然后就按照标准方法,新建MyService,在Manifest 中注册android:process = "com.test.myservice"
<service android:name=".MyService" android:process="com.test.myservice" android:enabled="true" android:exported="true"></service>
标准的数据传递方式不起作用,所以只能借用Messenger 或者是ADIL。我所会的ADIL是再另起一个应用,然后进行通信,至于同一应用中,我就不知道能不能做到了(反正我没用过)。所以根据网上找了两个使用messenger的方法
https://www.jianshu.com/p/ce1e35c84134
https://blog.csdn.net/yao_94/article/details/78374034?locationNum=5&fps=1
好了,废话不多说,直接上代码了。
首先实现activity往Service 发送消息,在Service中新建一个类继承Handler,new出Messenger
Messenger mMessenger = new Messenger(new ServiceHandler());
class ServiceHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 0: Bundle bundle = msg.getData(); if (bundle != null){ String mmsge = bundle.getString("type"); Toast.makeText(MyService.this, mmsge, Toast.LENGTH_SHORT).show(); /** 这儿要用 bundle 传值,如果直接用 client.obj = "响应返回" 是可能不会返回的*/ Messenger client = msg.replyTo;//获取到activity中Messenger对象 Message replyMessage = Message.obtain(null, 1); Bundle bundle1 = new Bundle(); bundle1.putString("kep","响应返回"); replyMessage.setData(bundle1); try { client.send(replyMessage); } catch (RemoteException e) { e.printStackTrace(); } } break; } } }
如果有东西需要初始化,可以在onCreate();中进行
FaceFeatureInitUtil.loadModel(MyService.this);
onBind()中也可以返回一个服务连接的提示。
@Override public IBinder onBind(Intent intent) { Toast.makeText(MyService.this, "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); }
在activity中同样要实现一个继承Handler的类,new出messenger
class returnHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: Bundle bundle = msg.getData(); if (bundle != null){ String result = bundle.getString("kep"); // Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); } break; } } }
private Messenger messenger2 = new Messenger(new returnHandler());
private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mMessenger = new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { } };
@Override protected void onStart() { super.onStart(); Intent intent = new Intent(MainActivity.this, MyService.class); bindService(intent, mServiceConnection, BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); unbindService(mServiceConnection); } }
在需要给service通信的地方发送消息
Message msg = Message.obtain(null, 1); Bundle bundle = new Bundle(); bundle.putParcelable("bitmap",processBitmap); bundle.putSerializable("Detect",tRetFaces[0]); bundle.putString("type","测试数据"); msg.setData(bundle); msg.replyTo = messenger2; //把activity中的messenger对象传过去,以便service再发送消息回来 try { mMessenger.send(msg); } catch (Exception e) { e.printStackTrace(); }这样同一应用中的跨进程间通信就完成了。