2

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.

benjamin
  • 304
  • 4
  • 13

2 Answers2

0

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.

Yavor Mitev
  • 1,363
  • 1
  • 10
  • 22
  • Is there a problem with onNewIntent? I thought this is he way to go, just need to prevent the second activity from getting stopped. Anyway I'll also look into singeltons. btw I'm using java. – benjamin Sep 29 '21 at 15:18
  • You are saying that onNewIntent is not working. Not me. Second of all - you should make a distinction between stopped and killed. They are totally different. I am not sure what exactly is preventing you to use onNewIntent. About creating Singletons in Java - there is a lot of info about it. But the modern way of doing things is ViewModel, LiveData, etc. If you make a complex interaction between screens, using mostly UI API - this is not ok. – Yavor Mitev Sep 29 '21 at 15:27
  • I'll clarify: When I start the app, act1 is created. I always start activities with the flags FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_CLEAR_TOP. Then I start act2 and it's also creating. Now I start act1 from act2, and it enters onNewIntent of act1 (so far so good). The problem is that act2 stops at this point, and when I start it again from act1 (it should resume to it), it creates act2 again – benjamin Sep 29 '21 at 15:32
  • Using Dagger/Hilt would be overkill for this (simple) case. Also no need for it to be a singleton. It can be a regular object which is created inside your own `Application` class. – Minas Mina Sep 29 '21 at 20:26
0

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 {
    
    private String theString = "";

    public void setTheString(String newValue) {
        theString = newValue;
    }

    public String getTheString( {
        return 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 extends Application {
    
    private Repository repository = new Repository();

    public Repository getRepository() {
        return 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 extends AppCompatActivity {

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

        Repository repository = ((MyApplication) getApplicationContext()).getRepository();
        System.out.println(repository.getTheString());
    }
}
Minas Mina
  • 2,058
  • 3
  • 21
  • 35
  • I have a few questions: 1. I don't know Kotlin, can you please explain the first (new) line of onCreate? 2. Why do I need the repository to extend Application, if it onlt stores some data? 3. How can I access the *same* repository object from both activities? – benjamin Sep 29 '21 at 21:16
  • I will answer the last question first: Using the code above (`val repository = (applicationContext as MyApplication).repository`) you are able to access the same repository object from both activities. You need to extend `Application` in order to keep the repository inside it. I can provide the sample in Java if it would help you more. – Minas Mina Sep 30 '21 at 09:53
  • I would appreciate a sample in Java, meanwhile I just use static lists – benjamin Oct 01 '21 at 12:20
  • I changed the sample to Java. – Minas Mina Oct 01 '21 at 13:58