Firebase云消息传递:访问onMessageReceived()中的UI元素

问题描述 投票:0回答:1

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

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

由于在主线程中没有调用onMessageReceived(),我使用Handler来执行主线程中的代码。

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

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

android firebase firebase-cloud-messaging
1个回答
0
投票

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

当你倾向于直接在onMessageReceived()中编写代码时,你的FirebaseMessagingService类会变得混乱。例如,如果您有4种不同类型的通知数据,并且每个数据都要求进行不同的活动。然后你的代码看起来像这样:

@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;

        }
    }

}

或者,如果您使用本地广播,那么您的代码将更加模块化和有条理。您的代码看起来像这样:

@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)将如下所示: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更改,并引导您进行更好的代码管理。

希望它有用!

© www.soinside.com 2019 - 2024. All rights reserved.