Android Service封装实战:基于Binder与接口的高效通信方案
通过封装Service,可以简化Service的使用和管理,提升代码的可维护性和复用性。无论是本地Service还是跨进程通信,封装都能让代码更加清晰和易于扩展。
1. 封装Service的步骤
1.1 创建基础Service类
创建一个基础的Service类,封装通用的逻辑(如启动、停止、绑定等)。
public abstract class BaseService extends Service {
private final IBinder binder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class LocalBinder extends Binder {
public BaseService getService() {
return BaseService.this;
}
}
// 启动Service
public static void startService(Context context, Class<? extends BaseService> serviceClass) {
Intent intent = new Intent(context, serviceClass);
context.startService(intent);
}
// 停止Service
public static void stopService(Context context, Class<? extends BaseService> serviceClass) {
Intent intent = new Intent(context, serviceClass);
context.stopService(intent);
}
// 绑定Service
public static void bindService(Context context, Class<? extends BaseService> serviceClass, ServiceConnection connection) {
Intent intent = new Intent(context, serviceClass);
context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
// 解绑Service
public static void unbindService(Context context, ServiceConnection connection) {
context.unbindService(connection);
}
}
1.2 定义通信接口
定义一个接口,用于Service和Activity之间的通信。
public interface IServiceCallback {
void onTaskCompleted(String result);
}
1.3 实现具体的Service
继承BaseService,实现具体的业务逻辑,并通过接口回调与Activity通信
public class MyService extends BaseService {
private IServiceCallback callback;
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "Service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "Service started");
// 模拟长时间运行的任务
new Thread(() -> {
for (int i = 0; i < 10; i++) {
Log.d("MyService", "Task running: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (callback != null) {
callback.onTaskCompleted("Task completed successfully");
}
stopSelf(); // 任务完成后停止Service
}).start();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "Service destroyed");
}
// 设置回调接口
public void setCallback(IServiceCallback callback) {
this.callback = callback;
}
// 自定义方法供客户端调用
public void performTask(String taskName) {
Log.d("MyService", "Performing task: " + taskName);
}
}
1.4 在Activity中使用封装的Service
通过封装的BaseService方法启动、停止、绑定和解绑Service,并实现回调接口。
public class MainActivity extends AppCompatActivity {
private MyService myService;
private boolean isBound = false;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getService();
myService.setCallback(callback); // 设置回调接口
isBound = true;
Log.d("MainActivity", "Service connected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
Log.d("MainActivity", "Service disconnected");
}
};
private IServiceCallback callback = new IServiceCallback() {
@Override
public void onTaskCompleted(String result) {
Log.d("MainActivity", "Task completed: " + result);
runOnUiThread(() -> Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动Service
BaseService.startService(this, MyService.class);
// 绑定Service
BaseService.bindService(this, MyService.class, connection);
// 调用Service中的方法
findViewById(R.id.button).setOnClickListener(v -> {
if (isBound) {
myService.performTask("Custom Task");
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 解绑Service
if (isBound) {
BaseService.unbindService(this, connection);
isBound = false;
}
}
}
2. 封装Service的进阶功能
2.1 支持多个回调接口
如果需要支持多个回调接口,可以使用List来存储回调对象。
public class MyService extends BaseService {
private List<IServiceCallback> callbacks = new ArrayList<>();
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "Service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "Service started");
// 模拟长时间运行的任务
new Thread(() -> {
for (int i = 0; i < 10; i++) {
Log.d("MyService", "Task running: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (IServiceCallback callback : callbacks) {
callback.onTaskCompleted("Task completed successfully");
}
stopSelf(); // 任务完成后停止Service
}).start();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "Service destroyed");
}
// 添加回调接口
public void addCallback(IServiceCallback callback) {
callbacks.add(callback);
}
// 移除回调接口
public void removeCallback(IServiceCallback callback) {
callbacks.remove(callback);
}
// 自定义方法供客户端调用
public void performTask(String taskName) {
Log.d("MyService", "Performing task: " + taskName);
}
}
在Activity中添加和移除回调接口:
3. 总结
通过Binder和接口的方式,实现Service与Activity之间的通信。这种方式更加灵活,适合在同一进程内进行通信。通过封装Service,可以简化代码并提升可维护性。