首先给出综述,一共有4中形式:
intent、messenger、绑定服务以及广播
。
Intent
设定现在一个app,包含一个计时器功能,用户点击activity启动按钮执行计时器,并且在service中执行计时的操作;同时,activity还要获取当前的计时时间并显示在界面上。
给出伪代码:
// 在Activity中启动Service,并传递数据
Intent intent = new Intent(this, TimerService.class);
intent.putExtra("start_time", System.currentTimeMillis());
startService(intent);
// 在Service中获取传递的数据
long startTime = getIntent().getLongExtra("start_time", 0);
Messenger
首先阐述一下messenger
的原理:
客户端
,创建一个Handler
对象,并且将其和一个Messenger
实例关联起来;接收端也叫做服务端
,需要创建一个Handler
对象,并且将其和一个已经存在的Messenger
实例关联起来。bindService
方法,把客户端和服务端绑定,获取到一个IBinder
对象;将这个IBinder
对象传递给Messenger构造函数
,在客户端创建Messenger对象
;在服务端,利用onBind
方法返回一个IBinder对象
,供客户端使用。messenger
发送消息:在发送端,当需要将消息发送给服务端时,创建一个Message
对象,并设置其中的数据、目标Messenger
等属性;调用目标Messenger的send()
方法,将消息发送出去。Handler对象,并重写其handleMessage()
方法;这个方法会在服务端接收到消息时被调用,可以在该方法中处理收到的消息。Message对象的replyTo属性
获取到客户端的Messenger实例;服务端可以使用这个Messenger
对象将消息回复给客户端。类似于客户端发送消息的方式。给出示例的代码:
// 在Activity中创建Messenger对象,并将其作为参数传递给Service
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
// 处理从Service返回的消息
}
});
Intent intent = new Intent(this, TimerService.class);
intent.putExtra("messenger", messenger);
startService(intent);
// 在Service中处理消息并回复
Messenger messenger = (Messenger) getIntent().getParcelableExtra("messenger");
if (messenger != null) {
messenger.send(Message.obtain(null, MSG_TIME_UPDATED, currentTime));
}
同时,给出基于服务端和客户端的示例代码:
// TODO:服务端创建Handler并关联一个新的Messenger对象
Handler serviceHandler = new Handler() {
@Override
public void handleMessage(Message message) {
// 处理接收到的消息
switch (message.what) {
case 1:
// 执行相应操作
// 回复消息给客户端
Messenger clientMessenger = message.replyTo;
Message replyMessage = Message.obtain(null, 2);
// 设置回复消息中的数据
Bundle replyData = new Bundle();
replyData.putString("key", "reply value");
replyMessage.setData(replyData);
try {
clientMessenger.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
// 处理其他消息...
}
}
};
Messenger serviceMessenger = new Messenger(serviceHandler);
// 在onBind()方法中返回服务端的Messenger实例
IBinder onBind(Intent intent) {
return serviceMessenger.getBinder();
}
// 客户端创建Handler并关联一个新的Messenger对象
Handler clientHandler = new Handler() {
@Override
public void handleMessage(Message message) {
// 处理接收到的消息
switch (message.what) {
case 1:
// 执行相应操作
break;
// 处理其他消息...
}
}
};
Messenger clientMessenger = new Messenger(clientHandler);
// 将客户端与服务端绑定
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
// 客户端发送消息给服务端
if (serviceMessenger != null) {
Message message = Message.obtain(null, 1);
// 设置消息中的数据
Bundle data = new Bundle();
data.putString("key", "value");
message.setData(data);
// 设置消息中的回复Messenger
message.replyTo = clientMessenger;
try {
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
广播通信
直接给出如下伪代码实现:
// 在Activity中发送广播
Intent intent = new Intent("com.example.timer.broadcast");
intent.putExtra("current_time", currentTime);
sendBroadcast(intent);
// 在Service中注册广播接收器,在接收到广播时处理数据
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long currentTime = intent.getLongExtra("current_time", 0);
// 处理接收到的数据
}
};
@Override
public void onCreate() {
super.onCreate();
registerReceiver(receiver, new IntentFilter("com.example.timer.broadcast"));
}
共享数据源(例如数据库)
// 在Activity中写入数据
// 创建一个ContentValues对象,用于存储要写入的数据。
ContentValues values = new ContentValues();
// 使用put()方法将数据以键值对的形式存储到ContentValues对象中,其中"time"是键,currentTime是值。
values.put("time", currentTime);
// 传入相应的URI和ContentValues对象,将数据插入到指定的内容提供者(content provider)中。
getContentResolver().insert(Uri.parse("content://com.example.timerprovider/timer"), values);
// 在Service中读取数据
Cursor cursor = getContentResolver().query(Uri.parse("content://com.example.timerprovider/timer"),
null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
long currentTime = cursor.getLong(cursor.getColumnIndex("time"));
// 处理读取到的数据
cursor.close();
}