1

I am bit confused what is the right place to use Service (for background task).

This is my scenario:

I have a class that extends Broadcast receiver. It receives WiFi state changes. Depending on the state change, I call another class. This is a pure Java class, not extending any class.

This class is instantiated by passing the Context (received with the broadcast receiver). I need to pass the Context because, among other things, I access SharedPreferences, display a notification, etc. But this not a foreground activity.

Is this the correct way? Or should my class extend Service and work as a background task?

Is it wrong to pass the Context to initiate a class?

For example,

public class WifiStateBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
...
    WifiChangeReceptionClass wifiChanged = new WifiChangeReceptionClass(context);
    wifiChanged.showNotification();
...
}

What is wrong with this approach?

ColdFire
  • 6,764
  • 6
  • 35
  • 51
madu
  • 5,232
  • 14
  • 56
  • 96

4 Answers4

2

Try any of this:

public class WifiChangeReceptionClass{
    public static void showNotification(Context context){
        //showYourNotification
    }
}

Or

Create an Application class that has a static method to get it's context, like so.

public class MyApplication extends Application {
    ...
    public static MyApplication get(){
        return this;
    }
    ...
}

Then in your class, just call:

public class WifiChangeReceptionClass{
    public static void showNotification(){
        Context context = MyApplication.get();
        //showYourNotification
    }
}

Or

Just use dagger for your dependency injections. Check docs here

Ayokunle Paul
  • 243
  • 1
  • 8
1

It is wrong because context reference will be available as long as you are in onReceive() method. Once call back onReceive() method gets completed context will no longer be available.

Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58
  • Thanks. OK. But what if showNotification() returns? Meaning, use of Context will be within the onReceive(). – madu Mar 26 '18 at 13:23
  • 1
    To get the context all over the application you may use this link https://stackoverflow.com/questions/2002288/static-way-to-get-context-in-android – Abdul Waheed Mar 26 '18 at 13:26
1

It is absolutely fine as long as you are using the context within the lifecycle of broadcast receiver (you may pass it to any class). Since broadcast receiver and service, both run on UI thread, using service would not make much difference.

If you want to perform some network operation or long running operation, then you can instantiate a intent service from receiver.

1

Registering for broadcast receiver to get Wifi state changes might not from Android 7 its has disabled the CONNECTIVITY_CHANGED.

Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare the broadcast receiver in their manifest. Apps will still receive CONNECTIVITY_ACTION broadcasts if they register their BroadcastReceiver with Context.registerReceiver() and that context is still valid.

This includes connectivity change. The better option is to use JobScheduler. Refer this link

As mentioned in the response, onReceive() of BroadcastReceiver is executed on main thread. Based on android documentation for broadcast receiver

As a general rule, broadcast receivers are allowed to run for up to 10 seconds before they system will consider them non-responsive and ANR the app. Since these usually execute on the app's main thread, they are already bound by the ~5 second time limit of various operations that can happen there (not to mention just avoiding UI jank), so the receive limit is generally not of concern. However, once you use goAsync, though able to be off the main thread, the broadcast execution limit still applies, and that includes the time spent between calling this method and ultimately PendingResult.finish().

If your WifiChangeReceptionClass is doing some extensive work, then refrain from running directly in onRecevie(). Instead start Service (you have to spawn a new thread thread) or IntentService

Community
  • 1
  • 1
Sagar
  • 23,903
  • 4
  • 62
  • 62