文章目录
1.service
在Android开发中,Service
是一个可以在后台长时间运行的组件,用于执行耗时操作或执行那些不需要与用户界面直接交互的任务。Service
不依赖于用户界面,即使用户切换到其他应用,Service
仍然可以继续运行。
Service 的主要用途
- 后台任务:执行耗时操作,如下载文件、播放音乐等。
- 跨进程通信:通过 AIDL 实现跨进程通信(IPC)。
- 定时任务:定期执行某些任务,如定时同步数据。
- 保持连接:维持与服务器的长连接,如实时聊天应用。
Service生命周期
- onCreate():当 Service 第一次被创建时调用。
- onStartCommand(Intent intent, int flags, int startId):每当通过 startService() 方法启动 Service 时调用。
- onBind(Intent intent):每当通过 bindService() 方法绑定到 Service 时调用。
- onUnbind(Intent intent):当所有客户端都解除绑定时调用。
- onDestroy():当 Service 被销毁时调用。
2.startService
循环打印日志Service:
java
public class MyService extends Service {
private static final String TAG = "ning";
private ExecutorService executorService;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "MyService onCreate");
// 创建一个单线程的ExecutorService
executorService = Executors.newSingleThreadExecutor();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "MyService onStartCommand");
// 提交一个任务到线程池,周期性地打印日志
executorService.submit(() -> {
while (true) {
Log.d(TAG, "MyService logging at " + System.currentTimeMillis());
try {
Thread.sleep(1000); // 每秒打印一次日志
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
return START_STICKY; // 服务被系统杀死后自动重启
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "MyService onDestroy");
// 关闭线程池
if (executorService != null) {
executorService.shutdownNow();
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "MyService onBind");
return null;
}
}
3.bindService
java
public class ServiceBindActivity extends AppCompatActivity {
private Button btn_bind;
private Button btn_cancel;
private Button btn_status;
private static final String TAG = "ning";
private MyBindService myBindService;
private boolean isBound = false;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
MyBindService.LocalBinder binder = (MyBindService.LocalBinder) service;
myBindService = binder.getService();
isBound = true;
// 调用 Service 的方法
myBindService.doSomething();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
isBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_bind);
btn_bind = findViewById(R.id.btn_bind);
btn_cancel = findViewById(R.id.btn_cancel);
btn_status = findViewById(R.id.btn_status);
Intent intent = new Intent(this, MyBindService.class);
btn_bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 绑定 Service
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
});
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 解绑 Service
unbindService(connection);
}
});
btn_status.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 获取 Service 状态
Log.d(TAG, "Service status: " + (myBindService == null ? "null" : "not null"));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 解绑 Service
if (isBound) {
unbindService(connection);
isBound = false;
}
}
}
java
public class MyBindService extends Service {
private static final String TAG = "ning";
private final IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
MyBindService getService() {
return MyBindService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "MyBoundService onCreate");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "MyBoundService onBind");
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "MyBoundService onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "MyBoundService onDestroy");
}
public void doSomething() {
Log.d(TAG, "MyBoundService doSomething called");
}
}
4.区别
在 Android 中,startService
和 bindService
都是用来启动和管理 Service
的方法,但它们的使用场景和行为有所不同。下面是它们的主要区别和使用场景:
startService
功能
- 启动型
Service
:通过startService
方法启动的Service
是启动型Service
,主要用于执行一次性的后台任务,如下载文件、上传数据等。 - 生命周期 :
Service
会一直运行,直到它自己调用stopSelf
方法或者外部调用stopService
方法将其停止。 - 回调方法 :主要使用
onStartCommand
方法来处理启动请求。
使用场景
- 后台任务:执行耗时操作,如下载文件、上传数据、处理大量数据等。
- 定时任务:定期执行某些任务,如定时同步数据。
- 无需与
Service
交互 :不需要与Service
进行持续的通信,只需要启动Service
并让它完成任务。
示例代码
java
// 启动 Service
Intent intent = new Intent(this, MyStartedService.class);
startService(intent);
// 停止 Service
stopService(intent);
bindService
功能
- 绑定型
Service
:通过bindService
方法启动的Service
是绑定型Service
,主要用于组件之间的交互,如Activity
与Service
之间的数据交换。 - 生命周期 :
Service
会一直运行,直到所有绑定的客户端都解除绑定。当最后一个客户端解除绑定时,Service
会调用onUnbind
方法,并最终调用onDestroy
方法。 - 回调方法 :主要使用
onBind
方法来返回一个IBinder
对象,用于客户端与Service
之间的通信。
使用场景
- 持续交互 :需要与
Service
进行持续的通信,如播放音乐、实时数据更新等。 - 跨进程通信 :通过
AIDL
实现跨进程通信。 - 资源共享 :多个组件共享同一个
Service
的资源。
示例代码
java
// 定义 ServiceConnection
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TAG", "onServiceConnected");
LocalBinder binder = (LocalBinder) service;
myBoundService = binder.getService();
isBound = true;
// 调用 Service 的方法
myBoundService.doSomething();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TAG", "onServiceDisconnected");
isBound = false;
}
};
// 绑定 Service
Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
// 解绑 Service
if (isBound) {
unbindService(connection);
isBound = false;
}
总结
-
startService
:- 用于启动一次性的后台任务。
Service
会一直运行,直到显式停止。- 主要使用
onStartCommand
方法处理任务。 - 适用于不需要与
Service
进行持续通信的场景。
-
bindService
:- 用于组件之间的持续交互。
Service
的生命周期与绑定的客户端相关,当所有客户端解除绑定时,Service
会停止。- 主要使用
onBind
方法返回IBinder
对象进行通信。 - 适用于需要与
Service
进行持续通信的场景。