Firebase云消息传递:在onMessageReceived()中访问UI元素 [英] Firebase Cloud Messaging: Accessing UI elements in onMessageReceived()

查看:84
本文介绍了Firebase云消息传递:在onMessageReceived()中访问UI元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的android应用程序中,我使用firebase云消息传递将一些数据发送到应用程序.

In my android app, I use firebase cloud messaging to send some data to app.

当应用程序通过onMessageReceived()收到消息时,我检查MainActivity当前是否可见(MainActivity具有对当前可见的MainActivity的静态引用),如果活动可见,则执行对活动进行一些修改.

When the app receives a message through onMessageReceived(), I check whether a MainActivity is currently visible (MainActivity has a static reference to the currently visible MainActivity), and if the activity is visible, I make some modifications to the activity.

由于在主线程中未调用onMessageReceived(),因此我使用Handler在主线程中执行代码.

Since onMessageReceived() is not called in the main thread, I use a Handler to execute the code in the main thread.

@Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        //Access UI
    });
}

这种方法有什么问题吗?如果没有,当收到云消息时,是否还有其他方法可以更新当前可见的UI?

Is there anything wrong with this approach? If not, are there any other ways to update the currently visible UI when a cloud message is received?

推荐答案

对于特定活动中的UI更改,应避免在onMessageReceived()中编写直接代码.您可以通过本地广播接收器进行频道传送.

You should avoid writing direct code in the onMessageReceived() for UI changes in a specific activity. You can channel it through Local broadcast receivers.

当您倾向于直接在onMessageReceived()中编写代码时,您的FirebaseMessagingService类将变得混乱.例如,如果您有4种不同的通知数据,而每种数据都要求进行不同的活动.然后您的代码将如下所示:

When you tend to write code directly in the onMessageReceived() your FirebaseMessagingService class will get cluttered. For instance if you have 4 different kind of notification data and each data calls for different activity. Then your code will look something like this :

@Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
    if(remoteMessage.getData() != null 
        && remoteMessage.getData().containsKey("notification_type")){
        switch(remoteMessage.getData().containsKey("notification_type")){
            case "type1":
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    //Access UI for some activity
                    .
                    .
                    .
                });
                break;
            case "type2":
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                     //Access UI for some activity
                    .
                    .
                    .
                });
                break;
            case "type3":
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                     //Access UI for some activity
                    .
                    .
                    .

                });
                break;
            case "type4":
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                     //Access UI for some activity
                    .
                    .
                    .

                });
                break;

        }
    }

}

或者,如果您使用本地广播,则您的代码将更加模块化和井井有条.您的代码将如下所示:

Alternatively, if you use local broadcast then your code will be much more modular and organised. Your code will look something like this:

@Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
    if(remoteMessage.getData() != null 
        && remoteMessage.getData().containsKey("notification_type")){
        Intent intent = new Intent();
        intent.putExtra("body",messageBody); // Put info that you want to send to the activity
        switch(remoteMessage.getData().containsKey("notification_type")){
            case "type1":
                intent.setAction("ACTION_1") // For activity1
                break;
            case "type2":
                intent.setAction("ACTION_2") //For activity2
                break;
            case "type3":
                intent.setAction("ACTION_3") //For activity3
                break;
            case "type4":
                intent.setAction("ACTION_4") //For activity4
                break;
        }
        sendBroadcast(intent);
    }

}

您的活动(例如activity1)将如下所示: 私有BroadcastReceiver mReceiver;

And your activity (eg. activity1) will look something like this: private BroadcastReceiver mReceiver;

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();

    IntentFilter intentFilter = new IntentFilter(
            "ACTION_1"); // Put appropriate action string 

    mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            //Get message from intent
            String msg_for_me = intent.getStringExtra("some_msg");
            //Do your UI Changes stuff here.

        }
    };
    //registering our receiver
    this.registerReceiver(mReceiver, intentFilter);
}

@Override
protected void onPause() {
    super.onPause();
    this.unregisterReceiver(this.mReceiver);//unregister receiver
}

据我所知,这将帮助您在活动本身内部编写UI更改代码,并引导您进行更好的代码管理.

According to me this will help you code your UI changes inside the activity itself and leads you towards a better code management.

希望它有用!

这篇关于Firebase云消息传递:在onMessageReceived()中访问UI元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆