title: Robust way to pass value back from Dialog to Activity on Android?
body: <p>This question has come up several times and I've read all the answers, but I haven't seen a truly robust way to handle this.  In my solution, I am using listeners from the calling <code>Activity</code> to the <code>AlertDialog</code> like so:</p>
  
  <pre><code>public class MyDialogFragment extends DialogFragment {
  
      public interface MyDialogFragmentListener {
          public void onReturnValue(String foo);
      }
  
      public void init(boolean someValue)
      {
          sSomeValue = someValue;
          listeners = new ArrayList&lt;MyDialogFragmentListener&gt;();
      }
      static boolean sSomeValue;
      private static ArrayList&lt;MyDialogFragmentListener&gt; listeners;
  
      public void addMyDialogFragmentListener(MyDialogFragmentListener l)
      {
          listeners.add(l);
      }
  
      public void removeMyDialogFragmentListener(MyDialogFragmentListener l)
      {
          listeners.remove(l);
      }
  
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
          AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
          builder.setTitle(R.string.title)
             .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int id) {
                     for (MyDialogFragmentListener listener : listeners) {
                         listener.onReturnValue("some value");
                     }
                 }
             })
             .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                     // User cancelled the dialog
                     // Nothing to do but exit
                 }
             });
          if (sSomeValue) {
              builder.setMessage(R.string.some_value_message);
          } else {
              builder.setMessage(R.string.not_some_value_message);
          }
          // Create the AlertDialog object and return it
          return builder.create();
      }
  }
  </code></pre>
  
  <p>Then in the calling <code>Activity</code>, I instantiate the object normally, pass in any arguments through <code>init</code> and set my listener.</p>
  
  <p>Here's the problem: when you rotate the device and change orientation while the dialog is open, both the <code>Activity</code> and <code>MyDialogFragment</code> objects get re-created.   To ensure that the input values don't get screwed up, I am setting my initialized values as <code>static</code>.  This feels hacky to me, but since there will only be one such dialog at a time, I am ok with it.  Where the problem comes in is with the return value.  The original listener will get called.  That's fine because the object still exists, but if there is a requirement to update the UI on the <code>Activity</code> (which there is), it won't get updated because the <em>new</em> <code>Activity</code> instance is now controlling the UI.</p>
  
  <p>One solution I am considering is casting <code>getActivity()</code> in the dialog class to my <code>Activity</code> and forcing the dialog itself to add a listener, rather than having the calling <code>Activity</code> do it.  But this just feels like a snowballing of hacks.</p>
  
  <p>What is the best practice for handling this gracefully?</p>