title: Android AIDL: Service-to-Activity communication
body: <p>I try to implement a Android AIDL communication strategy.
  I have an <em>Activity</em> and a <em>Service</em>.
  My <em>Activity</em> can successfully "talk" to my <em>Service</em>, but the reverse process does not seem to work.</p>
  
  <p>To summarize, as the <em>Activity</em> and the <em>Service</em> run in different processes, they cannot share any data throw the  <code>IBinder</code>  interface.
  So the  <code>onServiceConnected()</code>  method receive an AIDL interface instead.
  This interface is implemented Service-side and is aimed at being used (called) Activity-side.
  I use this <em>interface</em> to  <code>register()</code>  another AIDL.
  This new AIDL is implemented Activity-side and called Service-side through the AIDL interface.
  It act like a listener.
  Unfortunatly, the method of this new AIDL does not seem to be called.</p>
  
  <p>The <em>Service</em> run in its own process thanks to the following line in <code>AndroidManifest.xml</code>:</p>
  
  <h3>AndroidManifest.xml</h3>
  
  <pre><code>&lt;service android:name=".DemoService" android:process=":DemoServiceProcess" /&gt;
  </code></pre>
  
  <p>I have 2 AIDL files, one knowing the other.</p>
  
  <h3>IAidlActivity.aidl</h3>
  
  <pre><code>package app.test.aidldemo;
  
  interface IAidlActivity {
      void publish(int count);
  }
  </code></pre>
  
  <h3>IAidlService.aidl</h3>
  
  <pre><code>package app.test.aidldemo;
  
  import app.test.aidldemo.IAidlActivity;
  interface IAidlService {
      void startCounter();
      void register(IAidlActivity activity);
  }
  </code></pre>
  
  <p>The Service implements  <code>onBind()</code>  and run a <em>handler</em> in charge of incrementing a counter.</p>
  
  <h3>DemoService.java</h3>
  
  <pre><code>package app.test.aidldemo;
  import [...]
  public class DemoService extends Service
  {
      protected IAidlActivity aidlActivity;
  
      @Override
      public IBinder onBind(Intent intent)
      {
          return new IAidlService.Stub() {
              @Override
              public void startCounter() {
                  DemoService.this.startJob();
              }
              @Override
              public void register(IAidlActivity activity) {
                  DemoService.this.aidlActivity = activity;
              }
          };
      }
  
      public void startJob() {
          final Handler handler = new Handler();
          handler.post(new Runnable() {
              protected int count = 0;
              @Override
              public void run() {
                  if (count &lt; 500) {
                      count++;  // increment counter
                      try {  // then publish it to view
                          DemoService.this.aidlActivity.publish(count);  // interface, implemented activity-side
                      } catch (RemoteException e) {}
                      handler.postDelayed(this, 2000);  // 2sec.
                  }
              }
          });
      }
  }
  </code></pre>
  
  <p>The <em>Activity</em> only consist of a <em>TextView</em>.
  It start the <em>bounding</em> with the <em>Service</em> and update the view from time to time.
  It is also supposed to update the view when  <code>publish()</code>  is called.
  But that does not happen.</p>
  
  <h3>MainActivity.java</h3>
  
  <pre><code>package app.test.aidldemo;
  import [...]
  public class MainActivity extends Activity {
      protected TextView view;
      protected ServiceConnection connection;
  
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
  
          view = new TextView(this);
          setContentView(view);
          appendToView("Let's go!");
  
          connection = new ServiceConnection() {
              @Override
              public void onServiceConnected(ComponentName name, IBinder service) {
                  IAidlService aidlService = IAidlService.Stub.asInterface(service);
                  appendToView("IAidlService accessed");
                  IAidlActivity.Stub aidlActivity = new IAidlActivity.Stub() {
                      @Override
                      public void publish(int count) {
                          appendToView("*** Hey, new count is: " + count + "!! ***");
                      }
                  };
                  appendToView("IAidlActivity created");
                  try {
                      aidlService.register(aidlActivity);
                      aidlService.startCounter();  // interface, implemented service-side
                  }
                  catch (RemoteException e) { appendToView(e.toString()); }
              }
              @Override
              public void onServiceDisconnected(ComponentName name) {}
          };
  
          Intent intent = new Intent(MainActivity.this, DemoService.class);
          bindService(intent, connection, Context.BIND_AUTO_CREATE);
      }
  
      @Override
      public void onDestroy() {
          unbindService(connection);
          super.onDestroy();
      }
  
      public void appendToView(String text) {
          view.append(text + "\n");
      }
  }
  </code></pre>
  
  <p>I also try some variations like:</p>
  
  <ol>
  <li>run the  <code>appendToView("*** Hey...</code>  into  <code>runOnUiThread()</code></li>
  <li>delay the  <code>bindService()</code>  by using another handler + <code>postDelayed()</code></li>
  </ol>
  
  <p>My fallback technique would be to only use <em>IAidlService</em> and have a "watcher" Activity-side to constantly check the counter.
  But I would rather understand why it is not working, and what is the correct way to use AIDL.</p>