How can a remote Service send messages to a bound Activity?

后端 未结 4 1969
我寻月下人不归
我寻月下人不归 2021-02-08 19:44

I\'ve read the documentation about Bound Services, where it is shown that you can easily communicate through Messages from an Activity to a remote (i.e. not in the same

4条回答
  •  庸人自扰
    2021-02-08 20:07

    NOTE: This is only for in-process services and activities, not remote like question asked.

    Using a service to communicate with an activity involves making a listener that you can pass to the service from the activity.

    You need to make a service that is bound to an activity.

    The first step is making a service. In the service make sure you have a Binder object and the method to return a binder object. Below is an example that I used in my service to retrieve my binder. Also notice this binder has a method to set a listener, which will be saved in the service as a BoundServiceListener type field.

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class DownloadBgBinder extends Binder {
    
        public DownloadBgService getService() {
            // Return this instance of LocalService so clients can call public methods
            return DownloadBgService.this;
        }
    
        public void setListener(BoundServiceListener listener) {
            mListener = listener;
        }
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    

    Now you need to create some kind of interface that you can pass to the binder object that your service can use to send updates to. Below is my BoundServiceListener.

    public interface BoundServiceListener {
    
        public void sendProgress(double progress);
        public void finishedDownloading();
    }
    

    Now in your activity you need to create a ServiceConnection object that is used for binding to a service. SO add somethinglike this.

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
    
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            DownloadBgBinder binder = (DownloadBgBinder) service;
            mService = binder.getService();
            binder.setListener(new BoundServiceListener() {
    
                @Override
                public void sendProgress(double progress) {
                    // Use this method to update our download progress
                }
    
                @Override
                public void finishedDownloading() {
    
                }   
            });
    
            mBound = true;
        }
    

    Now the key line to notice here is

    binder.setListener(new BoundServiceListener() {
    
        @Override
        public void sendProgress(double progress) {
            // Use this method to update our download progress
        }
    
        @Override
        public void finishedDownloading() {
    
        }
    });
    

    This part is where I am actually sending my BoundServiceListener interface to the service class. The service class then uses that listener object here

        if (mListener!=null)
            mListener.finishedDownloading();
        if (mListener!=null)
            mListener.sendProgress(percent);
    

    Now you can put this anywhere you need to in your service class, and your activity will receive your progress update.

    Also be sure to include following in your activity to actually bind and start the service.

    Intent intent = new Intent(this, DownloadBgService.class);
    startService(intent);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    

    Keep in mind that even though you bind to a service, it it not actually started until you call start service. Binding to the service just connects the service to an activity. the startService() method calls the services

    onStartCommand(Intent intent, int flags, int startId)
    

    Also declare your service in your manifest

    
    

    Also unbind the service when the activity leaves by

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
    

    Hope this helps.

提交回复
热议问题