Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Interprocess Commuincation

Avatar for Thomas Thomas
January 18, 2017

Android Interprocess Commuincation

Avatar for Thomas

Thomas

January 18, 2017
Tweet

More Decks by Thomas

Other Decks in Programming

Transcript

  1. Declaring a service in the manifest <?xml version="1.0" encoding="utf-8"?> <manifest

    ... > ... <application ... > <service android:name=".ExampleService" /> ... </application> </manifest>
  2. Start Service Intent intent = new Intent(getActivity(), ShadowsocksService.class); intent.setAction(Constants.Action.SERVICE); connection

    = new ShadowsocksServiceConnection(); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); getActivity().startService(intent);
  3. Start Service Intent intent = new Intent(getActivity(), ShadowsocksService.class); intent.setAction(Constants.Action.SERVICE); connection

    = new ShadowsocksServiceConnection(); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); getActivity().startService(intent);
  4. Bind Service Intent intent = new Intent(getActivity(), ShadowsocksService.class); intent.setAction(Constants.Action.SERVICE); connection

    = new ShadowsocksServiceConnection(); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); getActivity().startService(intent);
  5. Bind Service Intent intent = new Intent(getActivity(), ShadowsocksService.class); intent.setAction(Constants.Action.SERVICE); connection

    = new ShadowsocksServiceConnection(); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); getActivity().startService(intent);
  6. AIDL interface ISocketService { int getState(); oneway void registerCallback(out ISocketServiceCallback

    callback); oneway void unregisterCallback(in ISocketServiceCallback callback); oneway void runShadowSocks(inout Config config); }
  7. AIDL public static com.shadark.app.aidl.ISocketService asInterface(android.os.IBinder obj) { if ((obj ==

    null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.shadark.app.aidl.ISocketService))) { return ((com.shadark.app.aidl.ISocketService) iin); } return new com.shadark.app.aidl.ISocketService.Stub.Proxy(obj); }
  8. AIDL public static com.shadark.app.aidl.ISocketService asInterface(android.os.IBinder obj) { if ((obj ==

    null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.shadark.app.aidl.ISocketService))) { return ((com.shadark.app.aidl.ISocketService) iin); } return new com.shadark.app.aidl.ISocketService.Stub.Proxy(obj); }
  9. AIDL public static com.shadark.app.aidl.ISocketService asInterface(android.os.IBinder obj) { if ((obj ==

    null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.shadark.app.aidl.ISocketService))) { return ((com.shadark.app.aidl.ISocketService) iin); } return new com.shadark.app.aidl.ISocketService.Stub.Proxy(obj); }
  10. AIDL public static com.shadark.app.aidl.ISocketService asInterface(android.os.IBinder obj) { if ((obj ==

    null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.shadark.app.aidl.ISocketService))) { return ((com.shadark.app.aidl.ISocketService) iin); } return new com.shadark.app.aidl.ISocketService.Stub.Proxy(obj); }
  11. AIDL Service private ISocketService.Stub mBinder = new ISocketService.Stub() { @Override

    public int getState() throws RemoteException { return mState; } . . . }
  12. AIDL Service private ISocketService.Stub mBinder = new ISocketService.Stub() { @Override

    public int getState() throws RemoteException { return mState; } . . . } @Override public IBinder onBind(Intent intent) { return mBinder; }
  13. AIDL Service private ISocketService.Stub mBinder = new ISocketService.Stub() { @Override

    public int getState() throws RemoteException { return mState; } . . . } @Override public IBinder onBind(Intent intent) { return mBinder; }
  14. AIDL Client @Override public void onServiceConnected(ComponentName name, IBinder binder) {

    try { mBinder = binder; binder.linkToDeath(SocketServiceManager.this, 0); mSocketService = ISocketService.Stub.asInterface(binder); registerCallback(); mCallback.onServiceConnected(); } catch (RemoteException e) { LogUtils.e(TAG, "onServiceConnected: " + e.getMessage()); } }
  15. AIDL Client @Override public void onServiceConnected(ComponentName name, IBinder binder) {

    try { mBinder = binder; binder.linkToDeath(SocketServiceManager.this, 0); mSocketService = ISocketService.Stub.asInterface(binder); registerCallback(); mCallback.onServiceConnected(); } catch (RemoteException e) { LogUtils.e(TAG, "onServiceConnected: " + e.getMessage()); } }
  16. Handle Bind Death @Override public void onServiceConnected(ComponentName name, IBinder binder)

    { try { mBinder = binder; binder.linkToDeath(SocketServiceManager.this, 0); mSocketService = ISocketService.Stub.asInterface(binder); registerCallback(); mCallback.onServiceConnected(); } catch (RemoteException e) { LogUtils.e(TAG, "onServiceConnected: " + e.getMessage()); } }
  17. Handle Bind Death @Override public void onServiceConnected(ComponentName name, IBinder binder)

    { try { mBinder = binder; binder.linkToDeath(SocketServiceManager.this, 0); mSocketService = ISocketService.Stub.asInterface(binder); registerCallback(); mCallback.onServiceConnected(); } catch (RemoteException e) { LogUtils.e(TAG, "onServiceConnected: " + e.getMessage()); } }
  18. Handle Bind Death @Override public void onServiceDisconnected(ComponentName name) { unregisterCallback();

    mCallback.onServiceDisconnected(); if (null != mBinder) { mBinder.unlinkToDeath(this, 0); mBinder = null; } }
  19. Handle Bind Death @Override public void onServiceDisconnected(ComponentName name) { unregisterCallback();

    mCallback.onServiceDisconnected(); if (null != mBinder) { mBinder.unlinkToDeath(this, 0); mBinder = null; } }
  20. Client Callback final protected RemoteCallbackList<ITaskCallback> callbacks = new RemoteCallbackList<>(); public

    void registerCallback(ITaskCallback cb) { if (cb != null) { mCallbacks.register(cb); } } public void unregisterCallback(ITaskCallback cb) { if(cb != null) { mCallbacks.unregister(cb); } }
  21. Client Callback final protected RemoteCallbackList<ITaskCallback> callbacks = new RemoteCallbackList<>(); public

    void registerCallback(ITaskCallback cb) { if (cb != null) { mCallbacks.register(cb); } } public void unregisterCallback(ITaskCallback cb) { if(cb != null) { mCallbacks.unregister(cb); } }
  22. Client Callback final protected RemoteCallbackList<ITaskCallback> callbacks = new RemoteCallbackList<>(); public

    void registerCallback(ITaskCallback cb) { if (cb != null) { mCallbacks.register(cb); } } public void unregisterCallback(ITaskCallback cb) { if(cb != null) { mCallbacks.unregister(cb); } }
  23. Client Callback public void callback(int val) { final int N

    = mCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { mCallbacks.getBroadcastItem(i).actionPerformed(val); } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // the dead object for us. } } mCallbacks.finishBroadcast(); }
  24. Client Callback public void callback(int val) { final int N

    = mCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { mCallbacks.getBroadcastItem(i).actionPerformed(val); } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // the dead object for us. } } mCallbacks.finishBroadcast(); }
  25. Messenger (Service) class IncomingHandler extends Handler { @Override public void

    handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; ... default: super.handleMessage(msg); } } }
  26. Messenger (Service) final Messenger mMessenger = new Messenger(new IncomingHandler()); class

    IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; ... default: super.handleMessage(msg); } } }
  27. Messenger (Service) final Messenger mMessenger = new Messenger(new IncomingHandler()); class

    IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; ... default: super.handleMessage(msg); } } }
  28. Messenger Service final Messenger mMessenger = new Messenger(new IncomingHandler()); @Override

    public IBinder onBind(Intent intent) { return mMessenger.getBinder(); }
  29. Messenger Service final Messenger mMessenger = new Messenger(new IncomingHandler()); @Override

    public IBinder onBind(Intent intent) { return mMessenger.getBinder(); }
  30. Messenger Client class IncomingHandler extends Handler { @Override public void

    handleMessage(Message msg) { switch (msg.what) { case MessengerService.MSG_SET_VALUE: mCallbackText.setText("Received from service: " + msg.arg1); break; default: super.handleMessage(msg); } } }
  31. Messenger Client class IncomingHandler extends Handler { @Override public void

    handleMessage(Message msg) { switch (msg.what) { case MessengerService.MSG_SET_VALUE: mCallbackText.setText("Received from service: " + msg.arg1); break; default: super.handleMessage(msg); } } } final Messenger mMessenger = new Messenger(new IncomingHandler());
  32. Messenger Client class IncomingHandler extends Handler { @Override public void

    handleMessage(Message msg) { switch (msg.what) { case MessengerService.MSG_SET_VALUE: mCallbackText.setText("Received from service: " + msg.arg1); break; default: super.handleMessage(msg); } } } final Messenger mMessenger = new Messenger(new IncomingHandler());
  33. Messenger Client final Messenger mMessenger = new Messenger(new IncomingHandler()); public

    void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); try { Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); mService.send(msg); } catch (RemoteException e) { } }
  34. Messenger Client final Messenger mMessenger = new Messenger(new IncomingHandler()); public

    void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); try { Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); mService.send(msg); } catch (RemoteException e) { } }
  35. Messenger Client final Messenger mMessenger = new Messenger(new IncomingHandler()); public

    void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); try { Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); mService.send(msg); } catch (RemoteException e) { } }