Tuesday, 29 May 2012

Bind service using IBinder class

Hello guys, Most of you are aware of the Binding service. You can bind the service with your Activity, Service and Content provider. You can not bind a service with Broadcast receiver.

There are total 3 ways to bind a service with application components


  1. Using IBinder class
  2. Using Messanger class
  3. Using AIDL
This post is for explain about IBinder class 

To implement IBinder class there are following steps

Steps for service
  1. Create a new Project name "BindServiceUsingBinderClass
  2. Create one Service in your application by extending the Service class 
  3. Create a class "LocalBinder" inside your service and extends "Binder" class in this class
  4. Implement the onBind() method of the service and return the instance of the "LocalBinder" class
Steps for activity
  1. Create one activity "Client" and create a instance of the "ServiceConnection" Interface
  2. Implement two methods of this interface onServiceConnected and onServiceDisconnected
  3. In  onServiceConnected method you will get instance of the iBinder so cast it to LocalBinder class which we have created in the service.
  4. Implement onStart() method and bind the service using bindService() method
  5. Implement onStop() method and unbind the service using unbindService() method
Source code of the IBinder class

Server.java


package com.example.bindservice.binder;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class Server extends Service{

 IBinder mBinder = new LocalBinder();

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

 public class LocalBinder extends Binder {
  public Server getServerInstance() {
   return Server.this;
  }
 }

 public String getTime() {
  SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  return mDateFormat.format(new Date());
 }
}


Client.java



package com.example.bindservice.binder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.bindservice.binder.Server.LocalBinder;

public class Client extends Activity {

 boolean mBounded;
 Server mServer;
 TextView text;
 Button button;
 
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        text = (TextView)findViewById(R.id.text);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
   
   public void onClick(View v) {
    text.setText(mServer.getTime());
   }
  });
    }

 @Override
 protected void onStart() {
  super.onStart();
  Intent mIntent = new Intent(this, Server.class);
        bindService(mIntent, mConnection, BIND_AUTO_CREATE);
 };
 
 ServiceConnection mConnection = new ServiceConnection() {
  
  public void onServiceDisconnected(ComponentName name) {
   Toast.makeText(Client.this, "Service is disconnected", 1000).show();
   mBounded = false;
   mServer = null;
  }
  
  public void onServiceConnected(ComponentName name, IBinder service) {
   Toast.makeText(Client.this, "Service is connected", 1000).show();
   mBounded = true;
   LocalBinder mLocalBinder = (LocalBinder)service;
   mServer = mLocalBinder.getServerInstance();
  }
 };
 
 @Override
 protected void onStop() {
  super.onStop();
  if(mBounded) {
   unbindService(mConnection);
   mBounded = false;
  }
 };
}



For more information read a tutorial from developer site.

24 comments:

  1. Excellent example! Very clean. Love it. No "fibonacci sequence"-style example where the message to convey is hidden beneath a pile of irrelevant code.

    Thanks

    ReplyDelete
  2. Is it posible to send text client to client using Ibinder class?? Thanks Sir. this is helpful

    ReplyDelete
  3. Very nice example. But i would like to know if you can put mServer.getTime() onCreate? instead of onButtonClick... because i have heard it is not possible. Wanted to know why it is not possible and what is the good way to overcome that issue? Let me know.

    ReplyDelete
  4. nice... between you and http://www.techotopia.com/index.php/Android_Local_Bound_Services_%E2%80%93_A_Worked_Example i think i can see my way through to implementing a bound service and activity set for my app... seriously though, this is one of the more complicated set ups i have run into in the android api's as of yet...

    ReplyDelete
  5. When I try to get the time gives this exception:

    java.lang.NullPointerException

    ReplyDelete
    Replies
    1. Can you know me where you are getting NullPointerException?

      Delete
  6. I have only one query ... how much time it takes for service to be bounded?
    Is there any need to wait for the service to get bounded n then do furthur operations ???

    ReplyDelete
    Replies
    1. The time for service to get bounded can not fixed. You can not say how much time service takes to get bounded. better way is maintain variable when service get bounded and check the variable before do any further operations. If you want to start operation as quickly as service get bounded then you can start sequence of operation from the method onServiceConnected. Hope this will solve your query.

      Delete
    2. can you post another example
      of two activities binding into a service?

      i might interest reading your article if you wouldn't mind to write that :D

      Delete
  7. Hi, thank you for amazing tutorial. I would like to ask is it possible bind service to Fragment? Because your tutorial works perfect in Activity but I can't find way how I can bind service to fragment. Thank you for any answer.

    ReplyDelete
  8. You can bind service using context and unfortunately Fragment does not have context.

    But you can use getActivity() method to get container activity and using that you can bind service.

    For example
    To bind getActivity().bindService() and to unbind service use getActivity().unbindService()

    Hope you are now clear.

    ReplyDelete
    Replies
    1. I very appreciate if you can look at the following example. This example does not have error's messages but also does not work correctly. However if I use this example in Activity class it works perfect. http://pastebin.com/nrAxUM6n
      I spent hours searching for reasons why it does not work. Unfortunately I still can not find a reason. Thank you for your time.

      Delete
    2. you resgister service class in Manifestfile then your code run

      Delete
  9. very nice tutorial . Thanks

    ReplyDelete
  10. In my Service implementation, i want to know the name and number of activities, currently bound to my Service. ? any help.

    ReplyDelete
  11. Is this the example for single application's Activity and Service class?
    As i can see the same package name for Activity and Service class!

    Thanks

    ReplyDelete
  12. First thanks for this nice blog... I have followed your many of tutorials and it helped me a lot!
    I need a help. I am working on a Music Player that uses Bound Service using AIDL. I bind service in MainActivity and then use this IBinder to communicate with service throughout the app.
    Is this the correct way? Can you please tell me is using ALDL for a music player is correct? Would it cause any problem. or is their any perfect way for that?

    Its very urgent for me. Any help is appreciated. Thanks.

    ReplyDelete
  13. Excellent example! Very clean.

    ReplyDelete
  14. Thanks a lot for posting this post, Your post has always been an informative source for me.
    android training

    ReplyDelete