Introduction
Messenger is used to creating inter-process communication (IPC). There are certain steps to create that type of communication in which communication is bidirectional; that is, between two processes.
This is also a client-server architecture let's say, a request is made from MainActivity to access the method in LocalService class.
A response generated in the LocalService class can be forwarded to MainActivity.
Steps to use Messenger
- The service class will implement a Handler that receives a callback for each call from a client(MainActivity).
- In this case, using Handler to create a Messenger object (which is a reference to the Handler).
- The Messenger creates an IBinder that the service returns to clients from onBind().
- Client Activity use the IBinder to instantiate the Messenger (that references the service's Handler), which the client uses to send Message objects to the service.
Creating button and text view to initiate communication and setting data respectively.
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="com.example.gkumar.servicebindermessanger.MainActivity">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Get Data"
- android:id="@+id/button"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true" />
- <TextView
- android:id="@+id/textView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Fetching Data From Api..."
- android:layout_below="@+id/button"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="82dp"
- android:visibility="invisible"/>
- </RelativeLayout>
- package com.example.gkumar.servicebindermessanger;
- import android.content.BroadcastReceiver;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.ServiceConnection;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.Messenger;
- import android.os.RemoteException;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MainActivity extends AppCompatActivity {
- // LocalService mService;
- Messenger mService = null;
- boolean mBound = false;
- TextView fetchDataTextView;
- Button mButton;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mButton = (Button) findViewById(R.id.button);
- fetchDataTextView = (TextView) findViewById(R.id.textView);
- mButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- fetchDataTextView.setVisibility(View.VISIBLE);
- onButtonClick(v);
- }
- });
- }
- @Override
- protected void onStart() {
- super.onStart();
- // Bind to LocalService
- Intent intent = new Intent(this, LocalService.class);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- }
- @Override
- protected void onStop() {
- super.onStop();
- // Unbind from the service
- if (mBound) {
- unbindService(mConnection);
- mBound = false;
- }
- }
- public void onButtonClick(View v) {
- if (mBound) {
- Message msg = Message.obtain(null, LocalService.FETCH_DATA_FROM_API, 0, 0);
- msg.replyTo = replyMessenger;
- try {
- mService.send(msg);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * Defines callbacks for service binding, passed to bindService()
- */
- private ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
- mService = new Messenger(service);
- mBound = true;
- }
- @Override
- public void onServiceDisconnected(ComponentName arg0) {
- mService = null;
- mBound = false;
- }
- };
- Messenger replyMessenger = new Messenger(new HandlerReplyMsg());
- // handler for message from service
- class HandlerReplyMsg extends Handler {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- String recdMessage = msg.obj.toString(); //msg received from service
- Toast.makeText(MainActivity.this, "Response Fetched", Toast.LENGTH_LONG).show();
- fetchDataTextView.setText(String.valueOf(recdMessage));
- }
- }
- }
- package com.example.gkumar.servicebindermessanger;
- import android.app.Service;
- import android.content.Intent;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.Messenger;
- import android.os.RemoteException;
- import android.util.Log;
- import android.widget.Toast;
- import com.android.volley.Request;
- import com.android.volley.Response;
- import com.android.volley.VolleyError;
- import com.android.volley.toolbox.StringRequest;
- import java.util.Random;
- /**
- * Created by gkumar on 4/11/2016.
- */
- public class LocalService extends Service {
- Messenger replyMessanger;
- static final int FETCH_DATA_FROM_API = 1;
- public static String responseData;
- @Override
- public IBinder onBind(Intent intent) {
- Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_LONG).show();
- return mMessenger.getBinder();
- }
- /**
- * Handler of incoming messages from clients.
- */
- class IncomingHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case FETCH_DATA_FROM_API:
- // Bundle bundle = msg.getData();
- Toast.makeText(LocalService.this,"Request Recieved",Toast.LENGTH_SHORT).show();
- replyMessanger = msg.replyTo;
- getDataFromAPI();
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
- final Messenger mMessenger = new Messenger(new IncomingHandler());
- /**
- * method for clients
- */
- public void getDataFromAPI() {
- String url = "http://api.androidhive.info/contacts/";
- StringRequest sr = null;
- sr = new StringRequest(Request.Method.GET, url,
- new Response.Listener<String>() {
- @Override
- public void onResponse(String response) {
- if (response != null) {
- responseData = response.toString();
- if (replyMessanger != null)
- try {
- Message message = new Message();
- message.obj = responseData;
- replyMessanger.send(message);//replying / sending msg to activity
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- Log.e("volleyerror", error.toString());
- }
- });
- VolleySingleton.getInstance(this).getRequestQueue().add(sr);
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.gkumar.servicebindermessanger">
- <uses-permission android:name="android.permission.INTERNET" />
- <application
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
- <activity android:name=".MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service
- android:name="com.example.gkumar.servicebindermessanger.LocalService"
- android:enabled="true"
- android:exported="false"
- />
- </application>
- </manifest>
- package com.example.gkumar.servicebindermessanger;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.support.v4.util.LruCache;
- import com.android.volley.RequestQueue;
- import com.android.volley.toolbox.ImageLoader;
- import com.android.volley.toolbox.Volley;
- public class VolleySingleton {
- private static VolleySingleton mInstance = null;
- private RequestQueue mRequestQueue;
- private ImageLoader mImageLoader;
- private VolleySingleton(Context context){
- mRequestQueue = Volley.newRequestQueue(context);
- mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() {
- private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
- public void putBitmap(String url, Bitmap bitmap) {
- mCache.put(url, bitmap);
- }
- public Bitmap getBitmap(String url) {
- return mCache.get(url);
- }
- });
- }
- public static VolleySingleton getInstance(Context context){
- if(mInstance == null){
- mInstance = new VolleySingleton(context);
- }
- return mInstance;
- }
- public RequestQueue getRequestQueue(){
- return this.mRequestQueue;
- }
- }
build.gradle
Now add Gradle dependencies to build.gradle (app) and sync project.
- apply plugin: 'com.android.application'
- android {
- compileSdkVersion 23
- buildToolsVersion "23.0.2"
- defaultConfig {
- applicationId "com.example.gkumar.servicebindermessanger"
- minSdkVersion 15
- targetSdkVersion 23
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- }
- dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- testCompile 'junit:junit:4.12'
- compile 'com.android.support:appcompat-v7:23.1.1'
- compile 'com.android.volley:volley:1.0.0'
- }
Running the Application
- Initiating the service using clicking the button and see the toast shows binding because onBind() method is called

- Request Received in handleMessage() of handler in LocalService.java Class you can see the toast showing "request received".

- Response Fetched in MainActivity, data received in handleMessage() of MainActivity.java as shown in code above and set it into textview.

Summary
Now, considering the previous articles, this article is little bit different, this is IPC via messenger. This article shows the use of handlers to enhance communication between service and activity.
Read more articles on Android

Kumaresh RajalingamPosted Apr 16, 2016, 8:34 AM
Good one
Debasis SahaPosted Apr 16, 2016, 2:37 AM
Nice One..
Vignesh ManiPosted Apr 15, 2016, 4:22 PM
Nice
Rahul Kumar SaxenaPosted Apr 15, 2016, 2:10 PM
Good one
Kuppurasu NagarajPosted Apr 15, 2016, 1:13 PM
Nice Sharing..
Praveen KumarPosted Apr 15, 2016, 12:48 PM
Very Nice