前台服务通知导致的android.os.TransactionTooLargeException异常

6
我正在编写一款安卓应用程序,该程序跟踪用户的位置,并在通知栏中显示旅程的距离、时间和价格,所有这些都可以在一个ForegroundService中追踪。该服务跟踪位置、价格和时间,我每秒更新一次通知。然而,在生产环境中,首次更新通知时,三星设备上运行Android 8.0+的设备会出现TransactionTooLargeException异常。
具体情况如下:
我从service中调用start方法:
public void start(MeasureService service) {
    service.startForeground(NOTIFICATION_ID, getNotification(0, 0, 0));
}

我从服务中调用update方法:

public void update(int price, float meters, long time) {
    mNotificationManager.notify(NOTIFICATION_ID, getNotification(price, meters, time));
}

实际上,这些调用是连续调用的,在update方法中出现了崩溃。这种连续调用是否会成为问题?
这是getNotification
private Notification getNotification(int price, float meters, long seconds) {
    if (mNotificationBuilder == null) {
        createNotificationBuilder();
    }
    return mNotificationBuilder
            .setCustomContentView(getSmallView(price))
            .setCustomBigContentView(getBigView(price, seconds, meters))
            .build();
}

其中getSmallViewgetBigView方法如下:

private RemoteViews getSmallView(int price) {
    String priceText = ...;
    mSmallView.setTextViewText(R.id.price, priceText);
    return mSmallView;
}

private RemoteViews getBigView(int price, long seconds, float meters) {
    String priceText = ...;
    String timeText = ...;
    String distanceText = ...;
    mBigView.setTextViewText(R.id.price, priceText);
    mBigView.setTextViewText(R.id.time, timeText);
    mBigView.setTextViewText(R.id.distance, distanceText);
    return mBigView;
}

以下是我创建 notificationBuilder 的步骤:

private void createNotificationBuilder() {
        NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
        ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
        mNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID);

    mNotificationBuilder = mNotificationBuilder
            .setSmallIcon(R.drawable.icon)
            .setOngoing(true)
            .setContentIntent(getOpenMeasurePageIntent());
}

并且 getOpenMeasurePageIntent

private PendingIntent getOpenMeasurePageIntent() {
    Intent launchMeasureIntent = new Intent(mContext, MainActivity.class);
    launchMeasureIntent.setAction(...);
    launchMeasureIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    return PendingIntent.getActivity(mContext, 0, launchMeasureIntent, 0);
}

这是我收到的崩溃日志:
Caused by: java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 560988 bytes
16  at android.app.NotificationManager.notifyAsUser(NotificationManager.java:319)
17  at android.app.NotificationManager.notify(NotificationManager.java:284)
18  at android.app.NotificationManager.notify(NotificationManager.java:268)
19  at com.myapp.service.measure.MyNotification.void update(int,float,long) <- this is called from the timer

我在网上找到了很多类似的问题,但它们通常都涉及在意图中传递大块数据,而我相信我没有这样做。你有什么想法,我可能做错了什么?

可能是 https://dev59.com/r2Eh5IYBdhLWcg3wIgQX#53222877 的重复问题。 - rds
你尝试过使用普通通知(而不是远程视图)启动前台服务吗? - Derek K
你能添加崩溃日志吗? - Abdul Aziz
通常情况下,当您传输大量数据时会发生这种情况。由于您经常更新通知,因此应仅在实际更改时尝试更新通知。同时,请查看https://medium.com/@mdmasudparvez/android-os-transactiontoolargeexception-on-nougat-solved-3b6e30597345,也许这可以帮助您了解问题... - Abdul Aziz
1个回答

0

我认为问题在于每秒更新通知。

解决方案

我建议只有当数据(如距离、价格)发生变化时才更新通知。


我每秒钟都在更新它,因为我正在显示经过的时间,但我会将其舍入到分钟并尝试一下! - Analizer
你可以使用其他方式来处理时间的流逝,比如处理程序。 - Mayur Dabhi
我仍然需要在交易中传递时间到通知。 - Analizer
有一个计时器小部件,您可以在远程视图中使用它来计算HH:MM:SS。在Android 6+上,它还可以倒计时。 - Eugen Pechanec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接