开发者

Passing data using Intents

开发者 https://www.devze.com 2023-03-02 04:04 出处:网络
I have two activities, Activity A and Activity B. I pass objects from Activity A to Activity B using intents. When i make changes to the Object in Acti开发者_StackOverflow中文版vity B the data changes

I have two activities, Activity A and Activity B. I pass objects from Activity A to Activity B using intents. When i make changes to the Object in Acti开发者_StackOverflow中文版vity B the data changes does not get reflected in Activity A. Have i missed out on something?


You are missing the fact that when you pass Object O from Activity A to Activity B via intents, activity B receives a COPY of object O. The way things work is that The object O gets serialized (converted to a sequence of bytes) and that sequence of bytes is then passed to Activity B. Then activity B recreates a copy of object O at the moment it was serialized. Any changes to the original object after it was serialized are not reflected in it's copy.

If both activities are part of the same application then just use a static field (or singleton) to communicate between them.


If you are passing a String, then it will not change since they are immutable.

Edit: See below for an alternative to Intent extras.


If you wish to use the architecture of passing immutable objects in messages you can create an immutable serializable data class. Pass an immutable instance of the data class in the intent using startActivityForResult. When the second activity is completed, send a different instance of the same immutable data class back to the first activity where it is trapped in onActivityResult. So in code, given an immutable class PasswordState.java with public final fields.

public final class PasswordState implements Serializable {

Create an instance of this immutable class and send it to the second activity as in:

  private void launchManagePassword() {
        Intent i= new Intent(this, ManagePassword.class); // no param constructor
        PasswordState outState= new PasswordState(lengthKey,
                timeExpire,
                isValidKey,
                timeoutType,
                password,
                model.getIsHashPassword(),
                model.getMinimumPasswordLength());  // NOT minimumHashedPasswordLength
        Bundle b= new Bundle();
        b.putSerializable("jalcomputing.confusetext.PasswordState", outState);
        i.putExtras(b);
        startActivityForResult(i,REQUEST_MANAGE_PASSWORD); // used for callback 
    }

The second activity returns a new object when it is done.

                PasswordState outPasswordState= new PasswordState(lengthKey,
                        timeExpire,
                        isValidKey,
                        timeoutType,
                        password,
                        isHashPassword,
                        minimumPasswordLength);
                Bundle b= new Bundle();
                b.putSerializable("jalcomputing.confusetext.PasswordState", outPasswordState);
                getIntent().putExtras(b);
                setResult(RESULT_OK,getIntent());   // call home with data on success only
                finish(); // go back <=== EXITS Here

Where it is trapped in Activity one.

    // ON_ACTIVITY_RESULT used for callback from ManageKeys.java
    protected void onActivityResult(int request, int result, Intent data)
    {
        switch (request){
        case REQUEST_MANAGE_PASSWORD:
            if (result == RESULT_OK) { // Success. New password.
                try {
                    PasswordState inMessage= (PasswordState)data.getSerializableExtra("jalcomputing.confusetext.PasswordState");
                    password= inMessage.password;
                    timeExpire= inMessage.timeExpire;
                    isValidKey= true;
                    writeToPrefs();  // support first launch and incoming tagged sms, save pw
                }
                catch(Exception e){ // data == null, extras == null
                    password= "";
                    isValidKey= false;
                    timeExpire= PasswordState.LONG_YEAR_MILLIS;
                    Log.d(Utilities.TAG,"FailedToGetResult",e); // will be stripped at runtime
                }                       
...
            break;
        }
    }

When you are done prototyping and the data objects are stable, you can refactor the code to use parcels instead of serializing objects. Since a copy is being sent between activities using serialization, it could be argued that the use of an immutable object is overkill. Using a mutable object and serializing a mutable object to and from the second activity would simplify the implementation.

Hope that helps. JAL

0

精彩评论

暂无评论...
验证码 换一张
取 消