I simply want to call methods of a local service from my activity. How can I do that ?
6 Answers
Here is an example that might help
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() {
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Client.this, "Service is disconnected", 1000).show();
mBounded = false;
mServer = null;
}
@Override
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;
}
};
}

- 2,820
- 24
- 41

- 932
- 6
- 8
-
1if the service is force stopped, will I get call to onServiceDisconnected? – Vivek MVK Sep 14 '16 at 19:18
-
67why is it so damn hard to call a simple fuction – Zulqurnain Jutt Nov 18 '16 at 23:33
-
@Mr.Z Maybe you were not Binding the service to activity in Android http://stackoverflow.com/questions/1916253/bind-service-to-activity-in-android – CrandellWS Jan 13 '17 at 12:40
-
this should be the correct answer. Thanks. You saved my time. – Dinith Rukshan Kumara Mar 09 '20 at 22:35
-
@Prateek Yadav: do we really need mBounded? can't we just check is mServer != null? – markzzz Feb 16 '23 at 14:33
There is sample code for this right in the Service documentation, under "Local Service Sample":
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
Also for those people suggesting aidl -- if your service and client are all part of your own .apk and running in the same process (the default behavior), there is no need for aidl; it is just additional complexity that doesn't give you anything.

- 5,499
- 2
- 48
- 64

- 90,665
- 16
- 140
- 154
How do you call a normal Java method?
A obj = new A();
obj.method();
Service is a Java class. So how would you call a service method?
serviceObj.method();
Now the real question is how do you create a Service object?
Service serviceObj = new Service();
Definitely not.
In Android, Service is a System component that is created, destroyed and managed by Android OS.
For creating a service object you need IBinder.
This is how you can get a Service object from IBinder.
Once you have a hold of serviceObject. It will work like any normal Java object.
The above thing explained in the figure is called Binding a Service.
Binding makes possible to observe a background service from an Activity. With binding, we can communicate in both ways ie Activity<--->Service.
Prateek Yadav has already provided an excellent code snippet. You can use that.
Few things to keep in mind
- Never forget to unbind the service else you will lead to ResourceLeak.
- You can call
startService(intent)
andbindService(mIntent, mConnection, BIND_AUTO_CREATE)
in any order. Binding and Starting a service are two independent things.

- 1
- 1

- 16,950
- 7
- 90
- 88
One way to do this is by defining an interface with Android's AIDL and making use of the Binder
subsystem to perform IPC. There is a great set of instructions at the link I posted. I'd start there and then post here if you have questions. Despite being a pretty complex topic (IPC) Android and the Binder
do a really good job of making it pretty dead simple (at least to get started, I'm sure you could make it complicated if you wanted to ;-) )
Edit As pointed out in the comments, this is unnecessary if the Service
and the client are running in the same process. Unless you specify otherwise, this is the default. However, it still works regardless, it just adds a bit more complexity.

- 35,167
- 12
- 80
- 109
-
4AIDL is only needed if the service and activity are in different applications. If your service and activity are local to you application (which is the common case), see response by @hackbod – odedfos Aug 04 '13 at 14:55
-
@odedfos You're partially right. The necessity of using AIDL depends on whether the caller and callee are in different _processes_ not necessarily different applications. Most of the time, applications only have one process so this isn't an issue but you can specify that a service runs in a different process from the UI even in the same application. – Chris Thompson Aug 05 '13 at 03:02
-
1Local services by definition don't use IPC, and the question is about local services, thus this answer is wrong. – User Aug 20 '13 at 09:50
-
@Ixx by default they don't but you can specify that they run in a separate process. Also, this does _work_ ergo it's not wrong, it's simply more complicated and requires more overhead than necessary if you're running the service in the same process as the client. – Chris Thompson Aug 20 '13 at 17:32
the Equivalent code for Kotlin
MainActivity.kt
private var mBounded = false
private var foregroundService: ForegroundService? = null
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
btn_start_service.setOnClickListener { startMyService(); }
btn_stop_service.setOnClickListener { stopMyService(); }
mConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
Toast.makeText(this@MainActivity, "Service is disconnected", Toast.LENGTH_SHORT)
.show()
mBounded = false
foregroundService = null
}
override fun onServiceConnected(name: ComponentName, service: IBinder) {
Toast.makeText(this@MainActivity, "Service is connected", Toast.LENGTH_SHORT).show()
mBounded = true
val mLocalBinder = service as LocalBinder
foregroundService = mLocalBinder.getServerInstance()
}
}
val startIntent = Intent(this, ForegroundService::class.java)
bindService(startIntent, mConnection as ServiceConnection, Context.BIND_AUTO_CREATE);
}
private fun startMyService() {
foregroundService!!.startService(this, "sdds")
}
private fun stopMyService() {
if (mBounded) {
mConnection?.let { unbindService(it) };
mBounded = false;
}
val stopIntent = Intent(this, ForegroundService::class.java)
stopService(stopIntent)
}
ForegroundService.kt
class ForegroundService : Service() {
private val CHANNEL_ID = "ForegroundService Kotlin"
var mBinder: IBinder = LocalBinder()
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
override fun onBind(intent: Intent?): IBinder? {
return mBinder
}
class LocalBinder : Binder() {
fun getServerInstance(): ForegroundService? {
return ForegroundService()
}
}}

- 999
- 1
- 10
- 22
I don't know where your problem is, please post some code. Using a Binder, the Activity can have access to the service object. See the examples in the API for creating a connection between activity and service.
Having the service object in your activity, you can simply call:
mService.yourMethod();
We could help you a lot better if you would exactly describe your problem and as I said, post some snippets.

- 1,271
- 1
- 12
- 19
-
6Why don't YOU put some links to useful resources? Post some skeleton snippets about how to bind a service and call its method subsequently? :) – Juri Jan 30 '11 at 20:44
-
@Juri http://stackoverflow.com/questions/1916253/bind-service-to-activity-in-android out of nowhere it was linked – CrandellWS Jan 13 '17 at 12:42