vxh.viet
4/7/2016 - 5:13 AM

Passing data to new Activity

Passing data to new Activity

Source: BigNerdRanch, Android Programming, The Big Nerd Ranch Guide (2nd Edition) (page 99).

Question: pass data to another activity for further processing.

Answer:

An activity may be started from several different places, so you should define keys for extras on the activities that retrieve and use them. Using your package name as a qualifier for your extra, as shown below, prevents name collisions with extras from other apps. Naively, you could return to CallingActivity and put the extra on the intent, but there is a better approach. There is no reason for CallingActivity, or any other code in your app, to know the implementation details of what CalledActivity expects as extras on its Intent. Instead, you can encapsulate that work into a newIntent(…) method.

public class CalledActivity extends Activity {
  private static final String EXTRA_STRING = "com.bignerdranch.android.geoquiz.answer_is_true";
  
  public static Intent newIntent(Context packageContext, String extraString) {
    Intent i = new Intent(packageContext, CalledActivty.class);
    i.putExtra(EXTRA_STRING, extraString);
    return i;
  }
...

Using a newIntent(…) method like this for your activity subclasses will make it easy for other code to properly configure their launching intents.

And in CallingActivity we do this:

...
mCheatButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    // Start CalledActivity
    String testString;
    Intent i = CalledActivity.newIntent(CallingActivity.this, testString);
    startActivity(i);
  }
});

Further Explaination:

The benefit of the newIntent pattern is that you get type safety for your parameters as well as more knowledge about what parameters an activity expects.

For example, you know that CalledActivity expects an intent like this:

Intent i = new Intent(this, CalledActivity.class);
i.putExtra("com.bignerdranch.android.geoquiz.answer_is_true", extraString);
startActivity(i);

CalledActivity requires that you pass in that extra with a String value. The problem with this is that I could pass in any extras I want. There's no checking to make sure that I have that String extra. I could add no extras or I could even pass in a different type than a String:

Intent i = new Intent(this, CalledActivity.class);
i.putExtra("com.bignerdranch.android.geoquiz.answer_is_true", 10);
startActivity(i);

There is no compile-time verification that I'm passing in the right parameters. You'll only discover a problem when you run the app.

The newIntent pattern adds compile-time verification of these parameters. So, if I have the following newIntent method in CalledActivity:

public static Intent newIntent(Context packageContext, String extraString) {
  Intent i = new Intent(packageContext, CalledActivity.class);
  i.putExtra("com.bignerdranch.android.geoquiz.answer_is_true", extraString);
  return i;
}

Now, when I call this method:

Intent i = CalledActivity.newIntent(this, 10);
startActivity(i);

I can't pass in 10. I'll get a compile time error because CalledActivity expects a String.