如何将后台任务的一部分移至主线程? (火力基地)

时间:2018-08-23 14:12:13

标签: android firebase firebase-cloud-messaging

我正在举一个使用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);尝试将已到达文本的文本放置在主活动中,但出现以下错误消息:

“只有创建视图层次结构的原始线程才能触摸其视图。”

我研究了一下,其解释是任务(我想像是接收)应该进入主线程:

runOnUiThread(new Runnable() {

    @Override
    public void run() {

        // Stuff that updates the UI

    }
});

问题是我不知道如何将类放置在主线程中。

还有另一种方法可以将该消息传递给主要活动吗?

欢迎任何评论或建议。

2 个答案:

答案 0 :(得分:1)

要将消息从服​​务传递到活动,最简单的方法是使用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);
        }
    }

MainActivity.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) {

    }

答案 1 :(得分:0)

这个问题实际上暗示了两个不同的问题。一个是:

  

如何将工作从后台线程转移到主线程?

  

get如何从服务的上下文中操纵当前正在运行的活动?

看来您已经为第二个问题找到了一些解决方案,但我怀疑这不是最可靠的解决方案(在活动中使用静态变量来跟踪该活动的实例)。无论如何,让我们想象一下这是可以的(但是稍后可能会给您带来麻烦)。

如果您对跟踪MainActivity实例的方式感到满意,则可以使用Handler将工作从消息传递服务的后台线程移至主线程:

new Handler().post(new Runnable() {
    public void run() {
        // code here will run on the main thread
    }
});

如果您想为活动提供更强大的解决方案来接收后台消息,请考虑使用事件总线,RxJava或Android体系结构组件LiveData来中继消息。

相关问题