0

Problem is a bit complex ,First of all both activity A and activity B activity B have android:noHistory = true in manifest. i have a custom serializable class suppose MyClass , that custom class is actually storing the context of the Activity B through constructor. And i have an object name obj in Activity B of type MyClass , Now i want to transfer this object to Activity C through intent when back button is pressed in Activity B.

From Activity A there is a button that open activity B without an issue, issue starts when i try to open activity C through B in onBackPressed(), with transferring serializable object . i am receiving NULL in Activity C.

[Updated] MyClass:

@SuppressWarnings("serial")
public class MyClass implements Serializable{

    private final String SHAREDKEY_HIGHSCORE = "High Scores";
    private final String FIELDKEY_HIGHSCORE = "HighScore";
    private final String FIELDKEY_HIGHTIME = "HighTime";
    private SharedPreferences sp;
    private SharedPreferences.Editor spEditor;

    public MyClass(Context context) {
        resetScore();
        sp = context.getSharedPreferences(SHAREDKEY_HIGHSCORE, Context.MODE_PRIVATE);
        spEditor = sp.edit();
    }

    public void resetScore(){
       newTime = 0;
       newScore = 0;
       highTime = 0;
       highScore = 0;
   }
}

Activity B:

public class ActivityB extends Activity {
    MyClass scores;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        scores = new MyClass(this);
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent(this, ActivityC.class);
        in.putExtra("Scores", scores);
        startActivity(intent);
    }
}

Activity C:

public class ActivityC extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_c);
        MyClass score = (MyClass) getIntent().getSerializableExtra("Scores");
        //score is null here always
    }
}

Manifest:

<activity
    android:name=".ActivityA"
    android:noHistory="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ActivityB"
    android:noHistory="true">

</activity>
<activity android:name=".ActivityC">

How can receive my custom class in activity C successfully ? please help

Zulqurnain Jutt
  • 298
  • 3
  • 20

3 Answers3

1

the problem is clearly here // i have to store context of Activity B no matter what.

NO! You do not have to store context of Activity B. You're trying to do it, for the wrong reasons.

In Android you must never try to keep an activity for longer than its lifecycle, and you should never try to Serialize a Context. It just doesn't work like this and that's the reason it will not work.

I'm putting this as an answer (instead of a comment) because that's what is is.

The solution to your problem is: re-think the architecture of your app. There're several different correct ways to passing or sharing information through activities, but trying to hold to a context and serialize it, is not one of them.

Budius
  • 39,391
  • 16
  • 102
  • 144
  • for the sake of argument just replace this line scores = new MyClass(this); of activity B with this scores = new MyClass(getApplicationContext()); still , problem is same , now even worse , i get exceptions – Zulqurnain Jutt Jul 18 '15 at 23:16
  • No need for "MyClass" to have a context object. Let it go. `Context` is provided for you by the system itself. Why do want to keep it? – vinitius Jul 18 '15 at 23:19
  • Actually i am doing some operations with sharedpreferences in MyClass , so i need context of application or activity to achieve that. – Zulqurnain Jutt Jul 18 '15 at 23:23
  • 1
    if all you're trying to do is to access `sharedpreferences` then your problem is infinitely simpler than that. Just make a self reference of the Application and use it AT THE MOMENT that you need it. Please refer to this answer on how to achieve it: http://stackoverflow.com/a/14057777/906362 – Budius Jul 18 '15 at 23:36
  • Lol @Budius by that time i access anything in `MyClass` object of Activity B in C, Activity B have been already destroyed . – Zulqurnain Jutt Jul 18 '15 at 23:43
  • First of all. I told you on my answer "must never try to keep an activity for longer than its lifecycle". The answer I pointed you to shows how to keep the application reference, NOT the activity. 2nd: You're the one having problems because you're trying to do something that you're not supposed to do and I'm the one with an "Editors choice", "Top developer" app with 10+million downloads on Google Play and 16K reputation on this site and I'm trying to point you in the correct direction. So don't "LOL" me, the joke is on you. – Budius Jul 18 '15 at 23:52
  • don't take joke seriously , i am just trying to solve my problem , and i really appreciate your help , but the link you just shared is insisting on changing my other files , is it so difficult so difficult to make a simple custom class to handle shared preference behaviours , i am updating my custom class please have a look. – Zulqurnain Jutt Jul 19 '15 at 00:00
  • If it is too difficult to change a different file in the project, then yes it is difficult to access shared preferences because it is part of the system, and to access the system you need the `Context`, and to access the `Context` outside the activity life cycle you have to change a different file. On the answer I linked to you, all your `MyClass` should do is call :`App.get().getSharedPreferences("name", 0)` – Budius Jul 19 '15 at 00:04
0

According to the Android documentation, when you declare an Activity with noHistory, it will not stay in the Activities Stack.

Your problem is happening after your onBackPressed finishes. Your Activity B context is cleaned by the Android OS GC, so when Activity C is created the pointer you had to that context is pointing to a null location.

I suggest using another architecture to pass information between your activities. Try searching for "Android extending Application class" in google :)

VulfCompressor
  • 1,390
  • 1
  • 11
  • 26
  • i know that , but my problem is not only with context but also with serialization of custom class . – Zulqurnain Jutt Jul 18 '15 at 23:17
  • I gave you the right way! Storing variables in an class that extends `Activity` is a good pratice to store values between activities. Search for that here on SO. – VulfCompressor Jul 19 '15 at 00:27
  • problem was not that simple did , you look at my updated `MyClass` – Zulqurnain Jutt Jul 19 '15 at 00:41
  • My answer still solves your problem. Clearly you didnt took a look at extending the Application object to tranfer values between activities/fragments in your app. You should really read about it. – VulfCompressor Jul 19 '15 at 03:16
0

I don't know what you're trying to achieve , but storing some Activity's Context is not gonna get you there. As @Budius stated , you should rethink what you're trying to do. The docs say about Context:

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

I don't see any reasons why one would need to keep and serialize it . Even if you need a "global" context , you can always call getApplication() inside your Activity.

vinitius
  • 3,212
  • 2
  • 17
  • 22