Home > Back-end >  Moving data back and forth between two open activities
Moving data back and forth between two open activities

Time:09-30

I have two activities- act1 and act2. I want to transfer a String from act1 to act2 when the user presses a button and after some computation I want to transfer a LatLng from act2 to act1, while keeping both activities open (or at least be able to restore every change in act2 from the app start).

Things I tried:

  • I saw here that if I add some flags to the intent I won't start new activities when using startActivity(). It works well getting from act1 to act2 but after starting act1 from act2 it stops act2, so in the next act2 opening it will make a new act2 copy.

  • I looked at the not-deprecated version of startActivityForResult, but since I need both of the activities open it's not what I want. I also want both of them to receive and return data.

  • From here, using static data structure in one activity may not be good practice.

  • I tried using extras and onNewIntent but couldn't make it work (since I can't keep both activities running).


Background (if relevant):

I have an app with two activities- main, which stores a ListView, and a map activity.

The map must have a marker placed in each saved address.

The list has two button types:

  1. "Add a new place...", that open the map activity, and adds a new marker where the user wants.
  2. -some address-, that open the map in the location corresponding to this address.

I need a way to pass the desired address to the map so it'll show this location, and I also need to pass the new saved address back to the main activity after creating a location.

CodePudding user response:

If you want a cleaner approach, where you care about architecture design:

  • Create a ViewModel per each activity
  • Create a Singleton, which the ViewModels access, and use it to share the data.

The Singleton could be something like:

object AddressManager{
    
    fun saveAddress(address: Address) {
        
    }
    
    fun getAddress(): Address{
        
    }
}

And of course, I would advise you to use Dagger and Hilt for the injection and not to use "object", but this is again more and more design ideas.

CodePudding user response:

You can use the repository pattern to store the data in a way accessible by all code in your app.

What is a repository?

A repository is a simple class that holds some data and provides access to it. Something like:

class Repository {
    
    var theString = ""
}

It's a good idea to give a more descriptive name to the repository. So if this is a repository that stores location data, you could name it LocationRepository.

Where should it be created?

A good place to keep the reference to it is the Application class. If you don't have one, you can define it like this:

class MyApplication : Application() {
    
    val repository = Repository()
}
  • It needs to extend the Application class provided by the android framework
  • You can also override the onCreate() method for more complex initialization, if necessary in your case

Define the application class in the manifest

In order for the android framework to know about your custom Application class you need to define it in the AndroidManifest.xml:

<application
        android:name=".MyApplication"
        ...

Access the repository in your activities

Now in each activity you can cast the application context into your application class:

class MainActivity : AppCompatActivity() {

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

        val repository = (applicationContext as MyApplication).repository
        println(repository.theString)
    }
}
  • Related