【问题标题】:Android - persisting data in ServiceAndroid - 在服务中持久化数据
【发布时间】:2018-01-27 09:56:31
【问题描述】:

我正在使用 Firebase 进行推送通知。问题是如果我的应用程序关闭并且只有 NotificationService 在后台运行,则通知不会保存。

如果我的应用程序正在运行,正在保存。

我应该如何在服务中保存数据?

NotificationReceiver extends FirebaseMessaginService {

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    saveNotification(buildNotificationObjet(remoteMessage));

    if(getPreference("displayNotifications") != 0) {
        sendNotification(remoteMessage.getNotification().getBody());
    }
}
}


private void saveNotification(Notification notification) {
        new PersistTask(getSharedPreferences(PREFERENCE_NAME,  Activity.MODE_PRIVATE)).execute(notification);
    }

保存在 PersistTask 中完成

private static class PersistTask extends AsyncTask<Notification, Void, List<Notification>> {

    SharedPreferences preferences;

    public PersistTask(SharedPreferences preferences) {
        this.preferences = preferences;
    }

    @Override
    protected List<Notification> doInBackground(Notification... paramNotification) {
        Gson gson = new Gson();
        Type type = new TypeToken<List<Notification>>(){}.getType();


        List<Notification> notifications = gson.fromJson(preferences.getString(PREFERENCE_LIST_NAME, ""), type);
        if(notifications == null) {
            notifications = new ArrayList<>();
        }

        notifications.addAll(Arrays.asList(paramNotification));

        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(PREFERENCE_LIST_NAME, gson.toJson(notifications));
        editor.apply();

        return notifications;
    }
}

【问题讨论】:

  • 我要在这里做一个假设(因此不是一个实际的答案)。我相信在 onMessageReceived() 返回后,firebase 服务没有更多工作要做并自行完成。这使得 Android 在您的 AsyncTask 可以执行之前杀死 VM。我对您的建议是创建一个IntentService 以在后台线程上安全地执行此操作。通知是 Parcelable 的,所以你可以传递一个 Intent 并从中调用getSharedPreferences
  • 不,我尝试在没有异步任务的情况下运行。我认为是与女巫服务启动中的上下文相关的东西。
  • 因此,使用 IntentService,上下文将是您自己的应用程序上下文。

标签: android service push-notification


【解决方案1】:

onMessageReceived 将在后台线程上调用,因此您不应在此处使用AsyncTask。直接在这个方法中同步地做你的事情。

【讨论】:

  • 这不能解决我的问题。两种方式我都试过了,
  • editor.commit()代替editor.apply()怎么样?
【解决方案2】:

问题是在使用 FireBase 时,推送通知有两种类型。

  1. 用于接收推送通知的注册服务不会处理带有“通知”的负载。
  2. 带有“数据”内容的负载,将由注册的服务处理。

来自 Firebase 文档 (https://firebase.google.com/docs/cloud-messaging/android/receive):

大多数消息类型都提供了onMessageReceived,但以下情况除外:

  • 当您的应用处于后台时发送的通知消息。在这种情况下,通知将传送到设备的系统托盘。默认情况下,用户点击通知会打开应用启动器。

  • 带有通知和数据负载的消息,包括后台和前台。在这种情况下,通知会被传递到设备的系统托盘,而数据负载会在启动器 Activity 的 Intent 的附加部分中传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    相关资源
    最近更新 更多