Mohammed Li
Mohammed Li

Reputation: 25

Android: Getting data from server to activity

My app polls data from server after it was notified by cloud messaging.

The data is fetched in GcmListenerService. My current approach is to use an Intent to transfer the data to the relevant activity via a broadcast receiver. This only works if the activity is in foreground.

How to store the data fetched by GcmListenerService such that the activity will update itself according to the fetched data as soon as it is resumed?

Upvotes: 0

Views: 764

Answers (1)

Janus Varmarken
Janus Varmarken

Reputation: 2336

You could use service binding.

Declare a Binder implementation as part of your service definition:

public class MyService extends Service {

    private final IBinder mBinder = new MyBinder();
    // Set this field whenever you receive data from the cloud.
    private ArrayList<MyDataType> latestCloudData;

    public class MyBinder extends Binder {
        public ArrayList<MyDataType> getLatestCloudData() {
            return MyService.this.latestCloudData;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

Bind and unbind to your service in your activity's onStart and onStop, respectively, by providing an implementation of ServiceConnection:

public class MyActivity extends Activity {
    // Provides an interface for communicating with the service.
    MyBinder mMyBinder = null;
    boolean mBound = false;

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to service
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

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

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder binder) {
            // Successfully bound, cast the IBinder to a MyBinder.
            MyBinder myBinder = (MyBinder) binder;
            // Can now use the MyBinder instance to communicate with the service.
            MyActivity.this.mMyBinder = myBinder;
            mBound = true;
            // Use the MyBinder to get the latest cloud data from the service and update your view.
            ArrayList<MyDataType> cloudData = MyActivity.this.mMyBinder.getLatestCloudData();
            MyActivity.this.updateViewWithCloudData(cloudData);
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };

    private void updateViewWithCloudData(ArrayList<MyDataType> data) {
        // Use the data to update your view here...
    }
}

See the Android Developer Guide for more information about Bound Services (the example above is a modified version of the example found there).

Also note that this will only help you when your activity moves from the background to the foreground (or is recreated). If you also want to receive updates while the activity is in the foreground, you should also perform a broadcast which your activity should listen for. However, you do not need to bundle the cloud data as part of this broadcast. The broadcast can simply be a simple notification prompting the activity to query the service for the new data using MyBinder.getLatestCloudData().

Upvotes: 1

Related Questions