2

I have a Serializable SpecialObject with some parameters (Location etc. in turn Serializable as well)

I would like to open a Fragment (MySpecialFragment) by an Activity (MySpecialActivity) by handling over a SpecialObject object. It works so far, I can trigger and open the MySpecialFragment but the SpecialObject is not handled over properly. I feel like I can't see the forest for the trees.

Debugging it:

val PARAM_BUNDLE = "bundle_extra"
val PARAM_SPECIAL_EXTRA = "special_bundle_extra"

class MySpecialActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_my_special)

    val sameIntentSht = intent // same as getIntent()

    val extras = intent.extras // same as getIntent().getExtras()
    val bundleExtras = intent.getBundleExtra(PARAM_BUNDLE)

    val extras2 = sameIntentSht.extras
    val bundleExtras2 = sameIntentSht.getBundleExtra(PARAM_BUNDLE)

    if(extras != null && extras2 != null && bundleExtras != null && bundleExtras2 != null) Timber.d("Jzst for debugging")

    FragmentHelper.inflateFragment(this, R.id.fragmentContainer, MySpecialFragment::class.java, extras)
}

companion object {
    fun createIntent(context: Context,
                     mySpecial: MySpecialObject?): Intent {
        val intent = Intent(context, MySpecialActivity::class.java)
        val bundle = Bundle()
        mySpecial?.let {
            bundle.putSerializable(PARAM_SPECIAL_EXTRA, mySpecial)
        }

        intent.putExtra(PARAM_BUNDLE, bundle)
        // intent.flags = FLAG_ACTIVITY_NEW_TASK
        return intent
    }
}
}

Instantiation createIntent(): Creating the Intent to launch the MySpecialActivity the createIntent() method works fine. When I debug into the intent object it has its bundle and that in turn has the Serializable MySpecialObject object.

Unpacking the Bundle onCreate(): As you can see in the onCreate() all the extra* and bundleExtra* objects don't have mMap

And the getExtras() directly from getIntent() (in Kotlin intent.extras) is not the same extras as sameIntentSht which is obviously the same val sameIntentSht = intent . You see in the debug intent.extras has 652 bytes and sameIntentSht.extras has 604 bytes !??!?

How can I handle over this bundle properly?

EDIT: I used RubenGees suggestion. Works so far:

val intent = Intent(context, MySpecialActivity::class.java)
mySpecial?.let {
    intent.putExtra(PARAM_SPECIAL_EXTRA, mySpecial)
}
// intent.flags = FLAG_ACTIVITY_NEW_TASK
return intent

But on the onCreate I had to copy the intent into sameIntentsht anyway: see here see mMap of extra and extra2 !?

Murat Ceven
  • 264
  • 1
  • 6
  • 1
    Why don't you call `intent.putExtra()` directly with your `Serializable` Object? There is a overload for it and that would avoid the construction of the `Bundle`. – rubengees May 19 '17 at 11:17
  • Thnx, worked so far, see EDIT section. – Murat Ceven May 19 '17 at 11:33
  • I'm not quite sure what is going on there, but doesn't `intent.getSerializableExtra(PARAM_SPECIAL_EXTRA) as MySpecialObject` work? (Since the intent may not contain the extra, you should also check `intent.hasExtra(PARAM_SPECIAL_EXTRA`). – rubengees May 19 '17 at 11:38

1 Answers1

1

Couple of things:

  • in the original code you're creating a Bundle containing a Bundle, and put that in the Intent. Thus you have one Bundle that's not really necessary. You can call putExtra directly on the Intent.

  • Calling intent.extras, or intent.getExtras() creates a copy of the extras bundle. So this is expected that you get two different bundles.

  • It is expected that when you debug, extras has empty mMap. Bundle has lazy semantics, and only the first call accessing the data will unparcel it, thus populating mMap.

I'd guess that initally you were creating an Intent containing a Bundle containing a Bundle, but when accessing you were trying to skip one step. I recommend deleting existing code and starting over:

  • creating Intent and putting special data using intent.putExtra(EXTRA_SPECIAL, specialObject) method;

  • and then retrieving special data by calling intent.getSerializableExtra(EXTRA_SPECIAL).

This is everything that's needed here.

wasyl
  • 3,421
  • 3
  • 27
  • 36