Service
与 Activity
之间可以通过绑定来实现通信;
我们在项目 ServiceSample
代码基础上动手实现这个功能吧。
实验步骤:
- 在
Service
中创建一个内部类,继承自Binder
; - 覆写
Service
的onBind()
和onUnbind()
函数; - 在
Activity
中创建ServiceConnection
类的实例; - 在
ServiceConnection
类实例中获取Binder
对象(在步骤 1 中创建的类型),通过该对象实现Activity
对Service
的通信; - 在
Activity
中实现绑定、解绑Service
的操作
1. 在Service
中创建一个内部类,继承自 Binder
;
编辑 MyService
创建一个内部类,
Java 代码:
public class MyBinder extends Binder {
public void doSomething() {
Log.i(TAG, "MyBinder : doSomething()");
}
}
Kotlin 代码:
class MyBinder: Binder() {
fun doSomething() {
Log.i(TAG, "MyBinder : doSomething()")
}
}
在内部类实现了一个函数 doSomething()
,打印日志。
2. 覆写Service
的 onBind()
和 onUnbind()
函数;
编辑 MyService
,覆写onBind()
和 onUnbind()
函数。
onBind()
函数在Service
与 Activity
成功绑定的时候回调;
onUnbind()
函数在Service
与 Activity
解除绑定的时候回调
Java 代码:
private final MyBinder mBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind()");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind()");
return super.onUnbind(intent);
}
Kotlin 代码:
private val mBinder = MyBinder()
override fun onBind(intent: Intent): IBinder {
Log.i(TAG, "onBind()")
return mBinder
}
override fun onUnbind(intent: Intent?): Boolean {
Log.i(TAG, "onUnbind()")
return super.onUnbind(intent)
}
我们创建了一个 MyBinder
对象,并在onBind()
函数中返回该对象。
3. 在Activity
中创建 ServiceConnection
类的实例;
在 MainActivity
中创建一个 ServiceConnection
类的实例,
Java 代码:
private final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i(TAG, "onServiceConnected()");
if (iBinder == null) return;
MyService.MyBinder mBinder = (MyService.MyBinder) iBinder;
mBinder.doSomething();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i(TAG, "onServiceDisconnected()");
}
};
Kotlin 代码:
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
Log.i(TAG, "onServiceConnected()")
if (iBinder == null) return
val mBinder = iBinder as MyService.MyBinder
mBinder.doSomething()
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.i(TAG, "onServiceDisconnected()")
}
}
4. 获取Binder
对象(在步骤 1 中创建的类型),通过该对象实现Activity
对Service
的通信
在onServiceConnected()
函数中得到 IBinder
对象,它就是 MyBinder
的实例,我们可以调用它的函数、传参数,通过这个对象实现Activity
对Service
的通信,
5. 在Activity
中实现绑定、解绑Service
的操作
编辑布局文件 activity_main.xml
<LinearLayout 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:orientation="vertical"
android:gravity="center_horizontal"
android:padding="15dp"
tools:context=".MainActivity">
......
<Button
android:id="@+id/bindBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bind" />
<Button
android:id="@+id/unbindBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="unbind" />
</LinearLayout>
界面添加了两个按钮,分别用于控制绑定、解绑Service
添加事件监听
编辑 MainActivity
,给按钮加上事件监听,分别实现绑定、解绑Service
的操作。
Java 代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
......
Button bindBtn = findViewById(R.id.bindBtn);
bindBtn.setOnClickListener(view -> {
Log.i(TAG, "bindService clicked.");
Intent intent = new Intent(this, MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
});
Button unbindBtn = findViewById(R.id.unbindBtn);
unbindBtn.setOnClickListener(view -> {
Log.i(TAG, "unbindService clicked.");
unbindService(connection);
});
}
Kotlin 代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
......
val bindBtn = findViewById<Button>(R.id.bindBtn)
bindBtn.setOnClickListener {
Log.i(TAG, "bindService clicked.")
val intent = Intent(this, MyService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
val unbindBtn = findViewById<Button>(R.id.unbindBtn)
unbindBtn.setOnClickListener {
Log.i(TAG, "unbindService clicked.")
unbindService(connection)
}
}
运行项目
-
点击绑定按钮,查看日志:
-
点击解绑按钮,查看日志:
只要调用方Activity
和Service
之间的连接没有断开, Service
就会一直保持运行状态,直到被系统回收。
调用Context
的unbindService()
函数可以解除两者之间的绑定关系。