我举了一个使用 Firebase 向 Android 发送推送通知的示例。
接收消息的类如下:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
String message;
message = "From: " + remoteMessage.getFrom();
message += "Notification Message Body: " + remoteMessage.getNotification().getBody();
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
MainActivity.updateMessage(message);
}
}
MainActivity.updateMessage(message(;尝试将到达TextView的文本放在主活动中,但我收到以下错误消息:
"只有创建视图层次结构的原始线程才能触及其视图。">
我已经研究了一下,解释是任务(我想是接收(应该在主线程中:
runOnUiThread(new Runnable() {
@Override
public void run() {
// Stuff that updates the UI
}
});
问题是我不知道如何将类放在原始线程中。
有没有另一种方法可以将该消息传递给主活动?
欢迎任何意见或建议。
要将消息从服务传递到活动,最简单的方法是使用BroadcastReceiver
API。
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
String message;
message = "From: " + remoteMessage.getFrom();
message += "Notification Message Body: " + remoteMessage.getNotification().getBody();
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
// Send the message to your activity.
Intent intent = new Intent("FisebaseMessage");
intent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
主活动.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver((mMessageReceiver),
new IntentFilter("FisebaseMessage")
);
}
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get message that sent from the service
String message = intent.getExtras().getString("message");
// Update message in the activity
updateMessage(message);
}
};
private void updateMessage(String message) {
}
这个问题实际上隐含了两个不同的问题。 一个是:
如何将工作从后台线程移动到主线程?
和
get 如何从服务的上下文中操作当前正在运行的活动?
对于第二个问题,您似乎已经得到了一些解决方案,但我怀疑这不是最强大的解决方案(使用活动中的静态变量来跟踪该活动的实例(。 无论如何,让我们想象一下这没关系(但它可能会在以后给你带来问题(。
如果您对跟踪 MainActivity 实例的方式感到满意,则可以使用 Handler 将工作从消息传递服务的后台线程移动到主线程:
new Handler().post(new Runnable() {
public void run() {
// code here will run on the main thread
}
});
如果您希望活动有一个更强大的解决方案来接收后台消息,请考虑使用事件总线、RxJava 或 Android 架构组件 LiveData 来中继消息。