Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android service communicating with multiple fragments

I have an application that has a single activity that hosts several fragments in a sort of custom navigation drawer design. Two of these fragments depend on a service to return them json information to display. I want to be able to start the service on my splash screen to load the data I need then asynchronously communicate the json to these fragments.

I am new to android and programming in general so excuse me if my actions were ill informed but I first tried to register the fragments as receivers and then simply broadcast intents containing the json information in a bundle. This seemed to not work because sometimes the fragments would not be running when the service would broadcast the intent and miss the intent.

Then I decided to go with sticky intents but this resulted in stale information not to mention the inherit security concern.

What is the best way to have a service perform a background network request upon launching the app and then display the returned information later by any activity or fragment?

like image 499
feilong Avatar asked Nov 24 '25 01:11

feilong


1 Answers

Believe me, I tried a lot of third party approaches (service buses, observes, ...) in large enterprise projects and it turned out the native Android mechanisms are the fastest and robust ones, since they take advantage of the framework's benefits.

Thats why I would recommend the usage of LocalBroadcastManager along with BroadcastReceiver. In your activity (or your can event do this per fragment!) register in onStart and unregister in onPause a dedicated Receiver.

Use the LocalBroadcastManager in your service to communicate to all potential subscribers.

Example:

 public class YourActivity extends Activity{

        private BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            //...do the stuff you need to do depending on the received broadcas

        }

};

  private IntentFilter filter = new IntentFilter(UploadService.INTENT_ACTION_UPLOAD);

  protected onStart(){
      LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
  }

  protected onPause(){
      LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
  }
}

public class UploadService extends IntentService{
   public static final String INTENT_ACTION_UPLOAD = "com.your.package.INTENT_ACTION_UPLOAD";

   public onHandleIntent(){
      //upload
      LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(INTENT_ACTION_UPLOAD));
   }
}

In the BroadcastReceiver's onReceiveyou can then do the stuff you need to do depending on the received broadcast. If you need to differentiate more, you can use different actions or extras, for instance in your service:

...send(new Intent(INTENT_ACTION_SOMETHING_ELSE));

or

send(new Intent(...).putExtra(WAS_SUCCESSFUL, false));
send(new Intent(...).putExtra(DOWNLOADED_CONTENT, downloadedStuff);
like image 110
André Diermann Avatar answered Nov 25 '25 16:11

André Diermann