title: Passing listeners via Bundle in AlertDialogFragment - is it possible?
body: <p>I have a simple class:</p>
  
  <pre><code>public class AlertDialogFragment extends DialogFragment {
  
      private static final DialogInterface.OnClickListener DUMMY_ON_BUTTON_CLICKED_LISTENER = new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
              // do nothing
          }
      };
  
      public static final class Builder implements Parcelable {
  
          public static final Creator&lt;Builder&gt; CREATOR = new Creator&lt;Builder&gt;() {
              @Override
              public Builder createFromParcel(Parcel source) {
                  return new Builder(source);
              }
  
              @Override
              public Builder[] newArray(int size) {
                  return new Builder[size];
              }
          };
  
          private Optional&lt;Integer&gt; title;
          private Optional&lt;Integer&gt; message;
          private Optional&lt;Integer&gt; positiveButtonText;
          private Optional&lt;Integer&gt; negativeButtonText;
  
          public Builder() {
              title = Optional.absent();
              message = Optional.absent();
              positiveButtonText = Optional.absent();
              negativeButtonText = Optional.absent();
          }
  
          public Builder(Parcel in) {
              title = (Optional&lt;Integer&gt;) in.readSerializable();
              message = (Optional&lt;Integer&gt;) in.readSerializable();
              positiveButtonText = (Optional&lt;Integer&gt;) in.readSerializable();
              negativeButtonText = (Optional&lt;Integer&gt;) in.readSerializable();
          }
  
          @Override
          public void writeToParcel(Parcel out, int flags) {
              out.writeSerializable(title);
              out.writeSerializable(message);
              out.writeSerializable(positiveButtonText);
              out.writeSerializable(negativeButtonText);
          }
  
          @Override
          public int describeContents() {
              return 0;
          }
  
          public Builder withTitle(Integer title) {
              this.title = Optional.fromNullable(title);
              return this;
          }
  
          public Builder withMessage(Integer message) {
              this.message = Optional.fromNullable(message);
              return this;
          }
  
          public Builder withPositiveButton(int buttonText) {
              this.positiveButtonText = Optional.fromNullable(buttonText);
              return this;
          }
  
          public Builder withNegativeButton(int buttonText) {
              this.negativeButtonText = Optional.fromNullable(buttonText);
              return this;
          }
  
          private void set(AlertDialog.Builder dialogBuilder, final AlertDialogFragment alertDialogFragment) {
              if (title.isPresent()) {
                  dialogBuilder.setTitle(title.get());
              }
              if (message.isPresent()) {
                  dialogBuilder.setMessage(message.get());
              }
              if (positiveButtonText.isPresent()) {
                  dialogBuilder.setPositiveButton(positiveButtonText.get(), new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          alertDialogFragment.onPositiveButtonClickedListener.onClick(dialog, which);
                      }
                  });
              }
              if (negativeButtonText.isPresent()) {
                  dialogBuilder.setNegativeButton(negativeButtonText.get(), new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          alertDialogFragment.onNegativeButtonClickedListener.onClick(dialog, which);
                      }
                  });
              }
          }
  
          public AlertDialogFragment build() {
              return AlertDialogFragment.newInstance(this);
          }
      }
  
  
      private static final String KEY_BUILDER = "builder";
  
      private DialogInterface.OnClickListener onPositiveButtonClickedListener = DUMMY_ON_BUTTON_CLICKED_LISTENER;
      private DialogInterface.OnClickListener onNegativeButtonClickedListener = DUMMY_ON_BUTTON_CLICKED_LISTENER;
  
  
      private static AlertDialogFragment newInstance(Builder builder) {
          Bundle args = new Bundle();
          args.putParcelable(KEY_BUILDER, builder);
          AlertDialogFragment fragment = new AlertDialogFragment();
          fragment.setArguments(args);
          return fragment;
      }
  
      public void setOnPositiveButtonClickedListener(DialogInterface.OnClickListener listener) {
          this.onPositiveButtonClickedListener = listener != null ? listener : DUMMY_ON_BUTTON_CLICKED_LISTENER;
      }
  
      public void setOnNegativeButtonClickedListener(DialogInterface.OnClickListener listener) {
          this.onNegativeButtonClickedListener = listener != null ? listener : DUMMY_ON_BUTTON_CLICKED_LISTENER;
      }
  
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
          AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
          Builder builder = getArguments().getParcelable(KEY_BUILDER);
          builder.set(alertDialogBuilder, this);
          return alertDialogBuilder.create();
      }
  
  
  }
  </code></pre>
  
  <p>Now I have to set <em>on button click listeners</em> in <code>SimpleDialogFragment</code> directly, because I can't pass the <em>listeners</em> via <code>Bundle</code> (args). But I want to - so it would look like instantiating an <code>AlertDialog</code>:</p>
  
  <pre><code>AlertDialogFragment dialogFragment = new AlertDialogFragment.Builder()
                  .withTitle(R.string.no_internet_connection)
                  .withMessage(messageId)
                  .withPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                      }
                  }).build();
  dialogFragment.show(getSupportFragmentManager(), FRAGMENT_TAG_NO_INTERNET_CONNECTION);
  </code></pre>
  
  <p>But now I should set listeners this way:</p>
  
  <pre><code>AlertDialogFragment dialogFragment = new AlertDialogFragment.Builder()
                  .withTitle(R.string.no_internet_connection)
                  .withMessage(messageId)
                  .withPositiveButton(android.R.string.ok)
                  .build();
  dialogFragment.setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                      }
                  });
  dialogFragment.show(getSupportFragmentManager(), FRAGMENT_TAG_NO_INTERNET_CONNECTION);
  </code></pre>
  
  <p>Perhaps setting <em>on button click listeners</em> directly to <code>DialogFragment</code> instance, rather than passing them via <code>Bundle</code> arguments, is not safe, because the recommended way to pass arguments to <code>Fragment</code> is passing them via <code>Bundle</code> arguments.</p>
  
  <p>And I know that the recommended way to communicate with <code>Fragment</code>s in <em>Android</em> is to oblige <em>host activity</em> to implement <em>callback interface</em>. But this way it's not clear that <em>Activity</em> should implement this interface until <code>ClassCastException</code> will be thrown in runtime. And it also makes strong dependence - to use it somewhere outside <em>Activity</em> I should implement the <code>Callback</code> interface in <em>Activity</em>. So I cannot use it in <code>Fragment</code>s "independent" of <em>host</em> <em>Activities</em>: <code>prepareAlertDialogFragment().show(getActivity().getSupportFragmentManager(), "tag");</code></p>