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

Android Interprocess Commuincation

Thomas
January 18, 2017

Android Interprocess Commuincation

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) { } }