Service in Android part2

In my last tutorial, we learned the basics of service used in the android application.We have understood that what are the basic difference between the Service and Intent Service. We also learned basic of bound Service. If you have not checked the detail then do not wait, Please check this link Service in Android part1.

Now we got one more day to learn something new about the Service that used on the application side. In this article, we will learn about service which using the technique of Messenger and AIDL. Wow Sounds great :).

Bound Service (Messenger and AIDL)

In this article, I am focusing on the bound services which are running in the background in the different process in the single thread and multi-tread environment. If we talk about the Single thread for sending the message in a queue the first thing comes in mind is that Messenger.


Messenger 

Messenger will process the message in a different process by using IPC (Inter Process Communication) remote technique to communicate with client and server. Messenger will be coupled with the handler, hence all the task will be in queue process in a Single thread by Handler.

For bind the service what you need to do with pass the Messenger instance reference in onBind() method and pass the reference of handler while creating the Messenger instance. Here message will be carried in the format of the bundle with Messenger that it awesome. Let's see for example to create one service which runs in the different process by using Messenger which is the coupled by Handler.

import android.app.Service;
import android.app.Service;
import android.content.Intent;
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.support.annotation.Nullable;
import android.widget.Toast;

/**
 * Created by sunil on 2/26/2017.
 */

public class MyServiceIPC extends Service {

    public static final int JOB_1 = 1;
    public static final int JOB_RESPONSE_1 = 2;

    Messenger messenger = new Messenger(new IncomingHandler());

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {

            Message message;
            Bundle bundle = new Bundle();
            String messageText;

            switch (msg.what) {
                case JOB_1:
                    messageText = msg.getData().getString("message");
                    message = Message.obtain(null, JOB_RESPONSE_1);
                    Toast.makeText(getApplicationContext(),messageText , Toast.LENGTH_SHORT).show();
                    bundle.putString("message_res", messageText.toUpperCase());
                    message.setData(bundle);
                    Messenger activityMessenger = msg.replyTo;
                    try {
                        activityMessenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }

        }
    }
}
Now let's create activity class to bind this service to send the message to this server and again send back this response from server to client by using Messenger process by the handler.

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
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.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.example.testapp.R;

/**
 * Created by sunil on 2/26/2017.
 */

public class BindServiceIPCActivity extends AppCompatActivity {

    private Button btnSend;
    private EditText editText;
    private Messenger messenger;
    private boolean isBound;
    private final Messenger mActivityMessenger = new Messenger(
            new ResponseTakeHandler(this));


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_ipc);

        editText = (EditText)findViewById(R.id.messageEditText);
        btnSend = (Button)findViewById(R.id.sendButton);
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String messageText = editText.getText().toString();
                if (messageText.isEmpty()){
                    Toast.makeText(BindServiceIPCActivity.this, "Please enter message", Toast.LENGTH_LONG).show();
                }else{
                    Message message = Message.obtain(null,MyServiceIPC.JOB_1);
                    Bundle bundle = new Bundle();
                    bundle.putString("message", messageText);
                    message.setData(bundle);
                    message.replyTo = mActivityMessenger;
                    try {
                        messenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!isBound) {
            // start service here
            Intent intent = new Intent(BindServiceIPCActivity.this, MyServiceIPC.class);
            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        isBound = false;
        messenger = null;
    }

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messenger = new Messenger(service);
            isBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBound = false;
            messenger = null;

        }
    };


    public class ResponseTakeHandler extends Handler{

        public ResponseTakeHandler(Context context){

        }
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case MyServiceIPC.JOB_RESPONSE_1:
                    String result = msg.getData().getString("message_res");
                    Toast.makeText(BindServiceIPCActivity.this, "Response: "+result, Toast.LENGTH_LONG).show();
                    break;
                default:
                    super.handleMessage(msg);
            }

        }
    }

}
Here also required the Service Connection to build the connection between the client and the server. The handler will process the response of Messenger and update the user interface. But one more thing does not forget to add this service in AndroidManifest.xml.
   
 <service android:name=".bindservice.ipc.MyServiceIPC" android:process=":remote"/>
Here is the XML file
   
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

   <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter message here"
        android:id="@+id/messageEditText"/>

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/sendButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:textColor="#fff"
        android:text="Send IPC Message"/>

</LinearLayout>
That great! Please see this snap to understand.



Wow, Messenger is awesome to communicate between server and client. In my next tutorial, we will check how is AIDL works in different process.

Thanks for reading this post.

Comments

Popular posts from this blog

NavigationView Drawer Expandable menu Item in ANdroid

Custom SeekBar (Discrete SeekBar) in android

Service LifeCycle