Merge pull request #10670 from Stypox/feed-oom
Fix OutOfMemory when fetching feed
This commit is contained in:
commit
482531836f
|
@ -58,7 +58,7 @@ class NotificationHelper(val context: Context) {
|
|||
.setAutoCancel(true)
|
||||
.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
||||
.setGroupSummary(true)
|
||||
.setGroup(data.originalInfo.url)
|
||||
.setGroup(data.url)
|
||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
||||
|
||||
// Build a summary notification for Android versions < 7.0
|
||||
|
@ -73,7 +73,7 @@ class NotificationHelper(val context: Context) {
|
|||
context,
|
||||
data.pseudoId,
|
||||
NavigationHelper
|
||||
.getChannelIntent(context, data.originalInfo.serviceId, data.originalInfo.url)
|
||||
.getChannelIntent(context, data.serviceId, data.url)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
|
||||
0,
|
||||
false
|
||||
|
@ -88,7 +88,7 @@ class NotificationHelper(val context: Context) {
|
|||
|
||||
// Show individual stream notifications, set channel icon only if there is actually
|
||||
// one
|
||||
showStreamNotifications(newStreams, data.originalInfo.serviceId, bitmap)
|
||||
showStreamNotifications(newStreams, data.serviceId, bitmap)
|
||||
// Show summary notification
|
||||
manager.notify(data.pseudoId, summaryBuilder.build())
|
||||
|
||||
|
@ -97,7 +97,7 @@ class NotificationHelper(val context: Context) {
|
|||
|
||||
override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {
|
||||
// Show individual stream notifications
|
||||
showStreamNotifications(newStreams, data.originalInfo.serviceId, null)
|
||||
showStreamNotifications(newStreams, data.serviceId, null)
|
||||
// Show summary notification
|
||||
manager.notify(data.pseudoId, summaryBuilder.build())
|
||||
iconLoadingTargets.remove(this) // allow it to be garbage-collected
|
||||
|
|
|
@ -277,14 +277,14 @@ class FeedLoadManager(private val context: Context) {
|
|||
notification.value!!.newStreams = filterNewStreams(info.streams)
|
||||
|
||||
feedDatabaseManager.upsertAll(info.uid, info.streams)
|
||||
subscriptionManager.updateFromInfo(info.uid, info.originalInfo)
|
||||
subscriptionManager.updateFromInfo(info)
|
||||
|
||||
if (info.errors.isNotEmpty()) {
|
||||
feedResultsHolder.addErrors(
|
||||
info.errors.map {
|
||||
FeedLoadService.RequestException(
|
||||
info.uid,
|
||||
"${info.originalInfo.serviceId}:${info.originalInfo.url}",
|
||||
"${info.serviceId}:${info.url}",
|
||||
it
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,29 +3,48 @@ package org.schabi.newpipe.local.feed.service
|
|||
import org.schabi.newpipe.database.subscription.NotificationMode
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
||||
import org.schabi.newpipe.extractor.Info
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfo
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||
import org.schabi.newpipe.util.image.ImageStrategy
|
||||
|
||||
/**
|
||||
* Instances of this class might stay around in memory for some time while fetching the feed,
|
||||
* because of [FeedLoadManager.BUFFER_COUNT_BEFORE_INSERT]. Therefore this class should contain
|
||||
* as little data as possible to avoid out of memory errors. In particular, avoid storing whole
|
||||
* [ChannelInfo] objects, as they might contain raw JSON info in ready channel tabs link handlers.
|
||||
*/
|
||||
data class FeedUpdateInfo(
|
||||
val uid: Long,
|
||||
@NotificationMode
|
||||
val notificationMode: Int,
|
||||
val name: String,
|
||||
val avatarUrl: String,
|
||||
val originalInfo: Info,
|
||||
val url: String,
|
||||
val serviceId: Int,
|
||||
// description and subscriberCount are null if the constructor info is from the fast feed method
|
||||
val description: String?,
|
||||
val subscriberCount: Long?,
|
||||
val streams: List<StreamInfoItem>,
|
||||
val errors: List<Throwable>,
|
||||
) {
|
||||
constructor(
|
||||
subscription: SubscriptionEntity,
|
||||
originalInfo: Info,
|
||||
info: Info,
|
||||
streams: List<StreamInfoItem>,
|
||||
errors: List<Throwable>,
|
||||
) : this(
|
||||
uid = subscription.uid,
|
||||
notificationMode = subscription.notificationMode,
|
||||
name = subscription.name,
|
||||
avatarUrl = subscription.avatarUrl,
|
||||
originalInfo = originalInfo,
|
||||
name = info.name,
|
||||
avatarUrl = (info as? ChannelInfo)?.avatars?.let {
|
||||
// if the newly fetched info is not from fast feed, then it contains updated avatars
|
||||
ImageStrategy.imageListToDbUrl(it)
|
||||
} ?: subscription.avatarUrl,
|
||||
url = info.url,
|
||||
serviceId = info.serviceId,
|
||||
// there is no description and subscriberCount in the fast feed
|
||||
description = (info as? ChannelInfo)?.description,
|
||||
subscriberCount = (info as? ChannelInfo)?.subscriberCount,
|
||||
streams = streams,
|
||||
errors = errors,
|
||||
)
|
||||
|
@ -34,7 +53,7 @@ data class FeedUpdateInfo(
|
|||
* Integer id, can be used as notification id, etc.
|
||||
*/
|
||||
val pseudoId: Int
|
||||
get() = originalInfo.url.hashCode()
|
||||
get() = url.hashCode()
|
||||
|
||||
lateinit var newStreams: List<StreamInfoItem>
|
||||
}
|
||||
|
|
|
@ -12,12 +12,11 @@ import org.schabi.newpipe.database.stream.model.StreamEntity
|
|||
import org.schabi.newpipe.database.subscription.NotificationMode
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionDAO
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
||||
import org.schabi.newpipe.extractor.Info
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfo
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo
|
||||
import org.schabi.newpipe.extractor.feed.FeedInfo
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||
import org.schabi.newpipe.local.feed.FeedDatabaseManager
|
||||
import org.schabi.newpipe.local.feed.service.FeedUpdateInfo
|
||||
import org.schabi.newpipe.util.ExtractorHelper
|
||||
import org.schabi.newpipe.util.image.ImageStrategy
|
||||
|
||||
|
@ -97,19 +96,15 @@ class SubscriptionManager(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun updateFromInfo(subscriptionId: Long, info: Info) {
|
||||
val subscriptionEntity = subscriptionTable.getSubscription(subscriptionId)
|
||||
fun updateFromInfo(info: FeedUpdateInfo) {
|
||||
val subscriptionEntity = subscriptionTable.getSubscription(info.uid)
|
||||
|
||||
if (info is FeedInfo) {
|
||||
subscriptionEntity.name = info.name
|
||||
} else if (info is ChannelInfo) {
|
||||
subscriptionEntity.setData(
|
||||
info.name,
|
||||
ImageStrategy.imageListToDbUrl(info.avatars),
|
||||
info.description,
|
||||
info.subscriberCount
|
||||
)
|
||||
}
|
||||
subscriptionEntity.name = info.name
|
||||
subscriptionEntity.avatarUrl = info.avatarUrl
|
||||
|
||||
// these two fields are null if the feed info was fetched using the fast feed method
|
||||
info.description?.let { subscriptionEntity.description = it }
|
||||
info.subscriberCount?.let { subscriptionEntity.subscriberCount = it }
|
||||
|
||||
subscriptionTable.update(subscriptionEntity)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue