Search code examples
androidandroid-serviceui-thread

How to communicate between activities in Android


I am new to Android (but not to java) and I am confused with Services, ViewModel, Broadcast things and other alternatives used to communicate between Activities. My communication needs are extremely basic.

Consider Midiscope's MainActivity. I want to do something like that, but with the Spinner to select the source on a different Activity. Basically one Activity for the Spinner (call it "SettingsActivity" but obviously cannot be a true Settings for reasons too long for this margin) and another Activity for the UI with the TextView, call it TextViewActivity. I am somewhat able to make it work if I share static variables to access the TextViewActivity from the Settings, so that I can create LoggingReceiver from the Settings but binding it to the TextViewActivity instead of Settings (this). Obviously this is not right (TM), so I attempted all the options I could google to no avail. What it the simplest way to accomplish this?

  • I tried ViewModel and the example in the documentation crashes at MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);  with error: no suitable constructor found for ViewModelProvider(MyActivity) (yes, I voted 1 star on that documentation page). The "solution" from the accepted answer to a question about it (i.e. using new ViewModelProvider.NewInstanceFactory()) crashes with java.lang.RuntimeException: Cannot create an instance of class com.example.MyViewModel

  • Then I tried IntentService as described at https://developer.android.com/guide/components/services but two things are unclear to me, so perhaps that's not the right approach for my problem:

    1. What should I do in onHandleIntent? My Intent does nothing per se, it should be only a pass-through between whatever comes from MIDI to my UI
    2. How can I access and use the IntentService from both the two Activities described above? Sure, the singleton pattern, but how to make sure I don't create the same problems that sharing a static instance of the Activity causes?

Solution

  • The problem is that I was thinking in the "Desktop" mode of developing java (e.g. with Swing) in which the windows are persistent objects, unlike in Android where Activities come and go at all the time.

    My solution is to make the LoggingReceiver constructor private and to make LoggingReceiver its own factory with a singleton pattern (i.e. with a getInstance() method returning the sole static instance in existence). Then both the SettingsActivity and the TextViewActivity can access it. The former to do its business of linking the receiver to the right MIDI source, the latter to register itself as the ScopeLogger. Obviously I need also a setScopeLogger() (called by TextViewActivity in its onCreate()) and some null checks in the LoggingReceiver.onSend() if mLogger is not set, since the original code assumed that would happen in the constructor. But this part "business as usual" in java.