Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put BroadcastReceiver in Android MVP?

Tags:

android

mvp

I have a BroadcastReceiver implementation that receives network connection events. its declared in the AndroidManifest.xml and is called by Android automatically when network events occur.

BroadcastReceiver:

public class ConnectivityChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v(TAG, "action: " + intent.getAction());
        Log.v(TAG, "component: " + intent.getComponent());
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <receiver
            android:name=".ConnectivityChangeReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

I'd like to use Google's MVP sample architecture described here for my app:

https://github.com/googlesamples/android-architecture/tree/todo-mvp/

Using the above architecture, just wondering:

  1. Where should my BroadcastReceiver be placed?

  2. If my BroadcastReceiver needs to write to the database, whats the best way of doing this?

  3. If my BroadcastReceiver needs to update the UI, whats the best way of doing this?

like image 997
Rory Avatar asked Sep 23 '16 10:09

Rory


People also ask

What is the use of BroadcastReceiver in Android?

Android BroadcastReceiver is a dormant component of android that listens to system-wide broadcast events or intents. When any of these events occur it brings the application into action by either creating a status bar notification or performing a task.

Where do I register and unregister broadcast receiver?

You should register and unregister your broadcast in onResume() and onPause() methods. if you register in onStart() and unregister it in onStop().

How pass data from BroadcastReceiver to activity in Android?

Step 1. Open your project where you want to implement this. Step 2. Open your BroadcastReceiver class from where you pass data to activity inside your onReceive() you need to start intent and pass data inside intent and start sendBroadcast() as shown bellow.


2 Answers

  1. Personally, I believe that events from the BroadcastReceiver should be delivered to the presenter.
  2. Based on statement 1, presenter holds reference to the Interactor/Contract/Use case that should handle db operations.

    BroadcastReceiver --event--> Presenter --> Interactor ---> Repository

  3. Based on statement 1, again the presenter should consume the event and make call to the View.

    BroadcastReceiver --event--> Presenter --> (maybe do some stuff, business logic) ---> View

Here is what I have, a minimal example snippet that sums up what I said:

  private class NetworkBroadcastReceiver23 extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //... redacted code.../
            boolean connected = activeNetworkInfo != null && activeNetworkInfo.isConnected();
            mPresenter.onConnectionChanged(activeNetworkInfo,connected);
        }
    }

Place the receiver in the activity, because from there you stream events to the presenter. This will ease testing the presenter for connection change. It's hard to achieve separation of concern for platform events, I wanted to keep my layers free from android sdk components and classes. Another way, that was pointed by Alex Shutov, is mixing MVP and Observer pattern if you go with considering BroadcastReceiver as external entity, rather than event source.

Yes, I agree that you can improve the method by getting rid of the NetworkInfo param.

like image 84
Nikola Despotoski Avatar answered Sep 21 '22 03:09

Nikola Despotoski


In MVP design pattern Model has all entities for connection with outer world (for example, Repository for fetching data and persisting it locally). Broadcast receiver is a input for external events, which, eventually, will modify model. Good comparison is a 'Input port' in Hexagonal architecture.

Presenter defines the way of displaying data from model, but all business logic, including reaction to another system or user events is supposed to be inside model.

View and Presenter can be changed dynamically depending on mode program running in, say, you want to use another version of UI, or more simplistic UI behaviour, but all logic must remain the same, including reaction to external events. That is why BroadcastReceiver should be placed inside model.

You should NEVER place Broadcast receiver into Activity, because Activity is a system container for (View), at least if you follow MVP pattern. In case your project is quite complex consider abstracting from BroadcastReceiver by some 'ExternalInput' interface, which can be easily mocked during testing and use it inside Model.

like image 32
Alex Shutov Avatar answered Sep 18 '22 03:09

Alex Shutov