How do I pass data between Activities in Android application?

Viewed 1178135

I have a scenario where, after logging in through a login page, there will be a sign-out button on each activity.

On clicking sign-out, I will be passing the session id of the signed in user to sign-out. Can anyone guide me on how to keep session id available to all activities?

Any alternative to this case

53 Answers

The easiest way to do this would be to pass the session id to the signout activity in the Intent you're using to start the activity:

Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("EXTRA_SESSION_ID", sessionId);
startActivity(intent);

Access that intent on next activity:

String sessionId = getIntent().getStringExtra("EXTRA_SESSION_ID");

The docs for Intents has more information (look at the section titled "Extras").

Passing Intent extras is a good approach as Erich noted.

The Application object is another way though, and it is sometimes easier when dealing with the same state across multiple activities (as opposed to having to get/put it everywhere), or objects more complex than primitives and Strings.

You can extend Application, and then set/get whatever you want there and access it from any Activity (in the same application) with getApplication().

Also keep in mind that other approaches you might see, like statics, can be problematic because they can lead to memory leaks. Application helps solve this too.

Updated Note that I had mentioned the use of SharedPreference. It has a simple API and is accessible across an application's activities. But this is a clumsy solution, and is a security risk if you pass around sensitive data. It's best to use intents. It has an extensive list of overloaded methods that can be used to better transfer many different data types between activities. Have a look at intent.putExtra. This link presents the use of putExtra quite well.

In passing data between activities, my preferred approach is to create a static method for the relevant activity that includes the required parameters launch the intent. Which then provides easily setup and retrieve parameters. So it can look like this

public class MyActivity extends Activity {
    public static final String ARG_PARAM1 = "arg_param1";
...
public static getIntent(Activity from, String param1, Long param2...) {
    Intent intent = new Intent(from, MyActivity.class);
        intent.putExtra(ARG_PARAM1, param1);
        intent.putExtra(ARG_PARAM2, param2);
        return intent;
}

....
// Use it like this.
startActivity(MyActvitiy.getIntent(FromActivity.this, varA, varB, ...));
...

Then you can create an intent for the intended activity and ensure you have all the parameters. You can adapt for fragments to. A simple example above, but you get the idea.

Try to do the following:

Create a simple "helper" class (factory for your Intents), like this:

import android.content.Intent;

public class IntentHelper {
    public static final Intent createYourSpecialIntent(Intent src) {
          return new Intent("YourSpecialIntent").addCategory("YourSpecialCategory").putExtras(src);
    }
}

This will be the factory for all your Intents. Everytime you need a new Intent, create a static factory method in IntentHelper. To create a new Intent you should just say it like this:

IntentHelper.createYourSpecialIntent(getIntent());

In your activity. When you want to "save" some data in a "session" just use the following:

IntentHelper.createYourSpecialIntent(getIntent()).putExtra("YOUR_FIELD_NAME", fieldValueToSave);

And send this Intent. In the target Activity your field will be available as:

getIntent().getStringExtra("YOUR_FIELD_NAME");

So now we can use Intent like same old session (like in servlets or JSP).

Kotlin

Pass from First Activity

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", "value")
startActivity(intent)

Get in Second Activity

val value = intent.getStringExtra("key")

Suggestion

Always put keys in constant file for more managed way.

companion object {
    val KEY = "key"
}

1st way: In your current Activity, when you create object of intent to open new screen:

  String value="xyz";
  Intent intent = new Intent(CurrentActivity.this, NextActivity.class);    
  intent.putExtra("key", value);
  startActivity(intent);

Then in the nextActivity in onCreate method, retrieve those values which you pass from previous activity:

  if (getIntent().getExtras() != null) {
      String value = getIntent().getStringExtra("key");
      //The key argument must always match that used send and retrive value from one activity to another.
  }

2nd way: You can create bundle object and put values in bundle and then put bundle object in intent from your current activity -

  String value="xyz";
  Intent intent = new Intent(CurrentActivity.this, NextActivity.class);  
  Bundle bundle = new Bundle();
  bundle.putInt("key", value);  
  intent.putExtra("bundle_key", bundle);
  startActivity(intent);

Then in the nextActivity in onCreate method, retrieve those values which you pass from previous activity:

  if (getIntent().getExtras() != null) {
      Bundle bundle = getIntent().getStringExtra("bundle_key");    
      String value = bundle.getString("key");
      //The key argument must always match that used send and retrive value from one activity to another.
  }

You can also use bean class to pass data between classes using serialization.

First Activity:

Intent intent = new Intent(getApplicationContext(), ClassName.class);
intent.putExtra("Variable name", "Value you want to pass");
startActivity(intent);

Second Activity:

String str= getIntent().getStringExtra("Variable name which you sent as an extra");

I use static fields in a class, and get/set them:

Like:

public class Info
{
    public static int ID      = 0;
    public static String NAME = "TEST";
}

For getting a value, use this in an Activity:

Info.ID
Info.NAME

For setting a value:

Info.ID = 5;
Info.NAME = "USER!";

you can communicate between two activities through intent. Whenever you are navigating to any other activity through your login activity, you can put your sessionId into intent and get that in other activities though getIntent(). Following is the code snippet for that :

LoginActivity:

Intent intent = new 
Intent(YourLoginActivity.this,OtherActivity.class);
intent.putExtra("SESSION_ID",sessionId);
startActivity(intent);
finishAfterTransition();

OtherActivity:

In onCreate() or wherever you need it call getIntent().getStringExtra("SESSION_ID"); Also make sure to check for if the intent is null and key you are passing in the intent should be same in both activities. Here is the full code snippet:

        if(getIntent!=null && getIntent.getStringExtra("SESSION_ID")!=null){
          sessionId = getIntent.getStringExtra("SESSION_ID");
}

However, I would suggest you to use AppSharedPreferences to store your sessionId and get it from that wherever needed.

Best way to pass data to one Activity to AnothetActivity by using Intent,

Check the code snipped

ActivityOne.java

Intent myIntent = new Intent(this, NewActivity.class);
myIntent.putExtra("key_name_one", "Your Data value here");
myIntent.putExtra("key_name_two", "Your data value here");
startActivity(myIntent)

On Your SecondActivity

SecondActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);

    Intent intent = getIntent();

    String valueOne = intent.getStringExtra("key_name_one");
    String valueTwo = intent.getStringExtra("key_name_two");
}

To access session id in all activities you have to store session id in SharedPreference.

Please see below class that I am using for managing sessions, you can also use same.

import android.content.Context;
import android.content.SharedPreferences;

public class SessionManager {

    public static String KEY_SESSIONID = "session_id";

    public static String PREF_NAME = "AppPref";

    SharedPreferences sharedPreference;
    SharedPreferences.Editor editor;
    Context mContext;

    public SessionManager(Context context) {
        this.mContext = context;

        sharedPreference = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = sharedPreference.edit();
    }


    public String getSessionId() {
        return sharedPreference.getString(KEY_SESSIONID, "");
    }

    public void setSessionID(String id) {
        editor.putString(KEY_SESSIONID, id);
        editor.commit();
        editor.apply();
    }   
}

//Now you can access your session using below methods in every activities.

    SessionManager sm = new SessionManager(MainActivity.this);
sm.getSessionId();



//below line us used to set session id on after success response on login page.

    sm.setSessionID("test");

Your data object should extend Parcelable or Serializable class

Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
mIntent.putExtra("data", data);
startActivity(mIntent);

To do this in Java:

startActivity(new Intent(this, MainActivity.class).putExtra("userId", "2"));

You can use intent class to send data between Activities. It is basically a message to OS where you describe source and destination of data flow. Like data from A to B activity.

In ACTIVITY A (the source):

Intent intent = new Intent(A.this, B.class);

intent.putExtra("KEY","VALUE");

startActivity(intent);

In Activity B (the destination)->

Intent intent =getIntent();

String data =intent.getString("KEY");

Here you will get data for key "KEY"

FOR BETTER USE ALWAYS KEYS SHOULD BE STORED IN A CLASS FOR SIMPLICITY AND IT WILL HELP IN MINNIMISE THE RISK OF TYPING ERRORS

Like this:

public class Constants{
public static String KEY="KEY"
}

Now In ACTIVITY A:

intent.putExtra(Constants.KEY,"VALUE");

In Activity B:

String data =intent.getString(Constants.KEY);

New and real time interaction between activites using callbacks:

- STEP 01: Implement a shared interface

public interface SharedCallback {
    public String getSharedText(/*you can define arguments here*/);
}

- STEP 02: Implement a shared class

final class SharedMethode {
    private static WeakReference<Context> mContext;

    private static SharedMethode sharedMethode = new SharedMethode();

    private SharedMethode() {
        super();
    }

    public static SharedMethode getInstance() {
        return sharedMethode;
    }

    public void setContext(Context context) {
        if (mContext != null)
            return;

        mContext = new WeakReference<Context>(context);
    }

    public boolean contextAssigned() {
        return mContext != null && mContext.get() != null;
    }

    public Context getContext() {
        return mContext.get();
    }

    public void freeContext() {
        if (mContext != null) mContext.clear();
        mContext = null;
    }
}

- STEP 03 :: Play with code in First Activity

public class FirstActivity extends Activity implements SharedCallback {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        // call playMe from here or there
        playMe();
    }

    private void playMe() {
        SharedMethode.getInstance().setContext(this);
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }

    @Override
    public String getSharedText(/*passed arguments*/) {
        return "your result";
    }

}

- STEP 04 :: Finalize the game in SecondActivity

public class SecondActivity extends Activity {

    private SharedCallback sharedCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        if (SharedMethode.getInstance().contextAssigned()) {
            if (SharedMethode.getInstance().getContext() instanceof SharedCallback)
                sharedCallback = (SharedCallback) SharedMethode.getInstance().getContext();

            // to prevent memory leak
            SharedMethode.freeContext();
        }

        // You can now call your implemented methodes from anywhere at any time
        if (sharedCallback != null)
            Log.d("TAG", "Callback result = " + sharedCallback.getSharedText());

    }

    @Override
    protected void onDestroy() {
        sharedCallback = null;
        super.onDestroy();
    }

}
  • STEP 05 :: you can also implement a backword callback (from First to Second) to get some results from SecondAvtivity or call some methods

Create new Intent inside your current activity

String myData="Your string/data here";
Intent intent = new Intent(this, SecondActivity.class);    
intent.putExtra("your_key",myData);
startActivity(intent);

Inside your SecondActivity.java onCreate() Retrieve those value using key your_key

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        String myData = extras.getString("your_key");
    }  
}

There are more than one ways of passing data between activities and other components of android app. One is using intents and parcelable as mentioned in lot of answers already.

Another elegent way is using Eventbus library.

From emitting activity:

EventBus.getDefault().postSticky("--your Object--");

In recv activity:

EventBus.getDefault().removeStickyEvent("--Object class--")

Other points to consider:

  1. Gives more freedom, You can pass complex objects without modifying them in any form.
  2. Not restricted to passing data between activities only, Once you set up the library, you can use it to pass data from one place to another in the app plumbing. For example use this for BottomSheetMenu to activity communication.
  3. Stable library.
  4. simplifies the communication between components
  5. decouples event senders and receivers
  6. performs well with UI artifacts (e.g. Activities, Fragments) and background threads
  7. avoids complex and error-prone dependencies and life cycle issues
  8. is fast; specifically optimized for high performance
  9. is tiny (~60k jar)
  10. is proven in practice by apps with 1,000,000,000+ installs
  11. has advanced features like delivery threads, subscriber priorities, etc.

In the Destination activity define like this

public class DestinationActivity extends AppCompatActivity{

    public static Model model;
    public static void open(final Context ctx, Model model){
          DestinationActivity.model = model;
          ctx.startActivity(new Intent(ctx, DestinationActivity.class))
    }

    public void onCreate(/*Parameters*/){
           //Use model here
           model.getSomething();
    }
}

In the first activity, start the second activity like below

DestinationActivity.open(this,model);

We can pass the values to another Activity by two ways(same kind of answer already posted but redcing code here i posted which tried through intent)

1.through Intent

  Activity1:
      startActivity(new Intent(getApplicationContext(),Activity2.class).putExtra("title","values"));

InActivity 2:

String recString= getIntent().getStringExtra("title");

2.Through SharedPreference

  Activity1:

SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); 
 // 0 - for private mode
Editor editor = pref.edit();
editor.putString("key_name", "string value"); // Storing string
editor.commit(); // commit changes

Activty2:
   SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); 

pref.getString("key_name", null); // getting String
 Intent intent = new Intent(getBaseContext(), SomeActivity.class);
 intent.putExtra("USER_ID", UserId);
 startActivity(intent);

 On SomeActivity : 

 String userId= getIntent().getStringExtra("("USER_ID");

You can work with intent

String sessionId = "my session id";

    startActivity(new Intent(getApplicationContext(),SignOutActivity.class).putExtra("sessionId",sessionId));

Using Bundle @link https://medium.com/@nikhildhyani365/pass-data-from-one-activity-to-another-using-bundle-18df2a701142
//copy from medium

           Intent I =  new Intent(MainActivity.this,Show_Details.class);

            Bundle b = new Bundle();


            int x = Integer.parseInt(age.getText().toString());
            int y = Integer.parseInt(className.getText().toString());

            b.putString("Name",name.getText().toString());

            b.putInt("Age",x);
            b.putInt("ClassName",y);

            I.putExtra("student",b);

            startActivity(I);

Using Intent @link https://android.jlelse.eu/passing-data-between-activities-using-intent-in-android-85cb097f3016

In other way you can pass data using Interfaces.

We have 2 activity A,B then what will I do, create an interface like:

public interface M{
    void data(String m);
}

then You Can call assign value to this method like below in Class A as code below:

public class A extends AppCompatActivity{
    
   M m;   //inteface name
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a);
       
        m= (M) getActivity();

    //now call method in interface and send data im sending direct you can use same on click

    m.data("Rajeev");
    }
}

Now You have to implement that interface in class B:

public class B extends AppCompatActivity implements M{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.b);
    }

    @Override
    public void data(String m) {
        you can use m as your data to toast the value here it will be same value what you sent from class A
    }
}
Related