Communication between Android Services and Activities

前端 未结 4 1975

I want to develop an Android App with three activities and two services.

The first Service, named WebClientService, calls a REST API every

相关标签:
4条回答
  • 2020-12-16 06:30

    You can bind the services to the activities and update your UI. Or you can use libraries like Otto or EventBus to create a publisher/subscriber dependency and notify your activities everytime your services publish an update of information.

    0 讨论(0)
  • 2020-12-16 06:33

    I think your approach is ok with BroadCastReceiver. However, BroadCastReceiver should be used for a global purpose (like communicating between 2 applications). If you intend to use BroadCastReceiver for your app only, I prefer using LocalBroadcastManager instead. Using LocalBroadcastManager is faster and more security when it can be caught only by your app.

    There's another way to communicate between your activitys and your services is using EventBus. It will be much easier than using BroadCastReceiver (especially in passing data between them).

    Update: About your update question:

    1. is it a good approach to just write my 30 seconds updates to the local db and allow the activities to update themselves every few seconds simply reading from the local db? --> Of course NO. You should let your activities update themselves when they need. When you update your local db, you should know that is there any changes or not. If there is any change, use LocalBroadcastmanager to notify your activity to update.
    2. Would that affect the performance too much? --> Yes, that do. The db connection will take time to execute and it will block your UI in some cases. in that case, you should use a thread with ExecutorService for each execute (insert, update...). One more thing to consider is updating that frequently will drain your phone battery very, very fast.
    0 讨论(0)
  • 2020-12-16 06:37

    Use event bus for this communication. EventBus allows publish-subscribe-style communication between components without requiring the components to explicitly register with one another (and thus be aware of each other). It is designed exclusively to replace traditional Java in-process event distribution using explicit registration.

    There are a lot of them:

    http://square.github.io/otto/

    https://github.com/greenrobot/EventBus

    This is an example of Otto usage:

    Bus bus = new Bus();
    
    bus.post(new AnswerAvailableEvent(42));
    
    @Subscribe public void answerAvailable(AnswerAvailableEvent event) {
        // TODO: React to the event somehow!
    }
    
    bus.register(this); // In order to receive events, a class instance needs to register with the bus.
    

    To post from any thread (main or background), in you case a Service and receive events on the main thread:

    public class MainThreadBus extends Bus {
      private final Handler mHandler = new Handler(Looper.getMainLooper());
    
      @Override
      public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
          super.post(event);
        } else {
          mHandler.post(new Runnable() {
            @Override
            public void run() {
              MainThreadBus.super.post(event);
            }
          });
        }
      }
    
    0 讨论(0)
  • 2020-12-16 06:40

    Best option ever:

    Use LocalBroadcastManager. More reference here.

    MyService.java:

    private LocalBroadcastManager localBroadcastManager;
    private final String SERVICE_RESULT = "com.service.result";
    private final String SERVICE_MESSAGE = "com.service.message";
    
    @Override
    public void onCreate() {
        super.onCreate();
    
       // Other stuff
    
       localBroadcastManager = LocalBroadcastManager.getInstance(this);
    }
    

    Add below method in service, whenever you want to update data from service to Activity, call method by passing Arguments.

    private void sendResult(String message) {
        Intent intent = new Intent(SERVICE_RESULT);
        if(message != null)
            intent.putExtra(SERVICE_MESSAGE, message);
        localBroadcastManager.sendBroadcast(intent);
    }
    

    HomeActivity.java:

    private BroadcastReceiver broadcastReceiver;
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_home);
        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String s = intent.getStringExtra(MyService.SERVICE_MESSAGE);
                // do something here.
            }
        };
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        LocalBroadcastManager.getInstance(this).registerReceiver((broadcastReceiver), 
            new IntentFilter(MyService.SERVICE_RESULT));
    }
    
    @Override
    protected void onStop() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
        super.onStop();
    }
    

    Hope this will help you.

    0 讨论(0)
提交回复
热议问题