Apply a new icon cache mechanism for memory improvement

- Avoid loading all app icons at once to decrease memory usage.
- Only load visible icons when entering the apps page.
- Reserve icon placeholder to alleviate icon loading flicker.
- Release icon cache when low memory or leaving apps page.

Bug: 187118427
Bug: 209898662
Test: manual check the smoothness and memory usage of apps pages.
Change-Id: Ifc3c2a73cc88d6e42739df4e8208445afa12e0ea
This commit is contained in:
Yanting Yang
2022-01-07 01:55:39 +08:00
parent 0128837312
commit 19bdc6ce67
6 changed files with 65 additions and 14 deletions

View File

@@ -43,6 +43,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -125,6 +126,8 @@ import com.android.settings.notification.app.AppNotificationSettings;
import com.android.settings.widget.LoadingViewController;
import com.android.settings.wifi.AppStateChangeWifiStateBridge;
import com.android.settings.wifi.ChangeWifiStateDetails;
import com.android.settingslib.applications.AppIconCacheManager;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
@@ -556,6 +559,7 @@ public class ManageApplications extends InstrumentedFragment
mApplications.release();
}
mRootView = null;
AppIconCacheManager.getInstance().release();
}
@Override
@@ -1323,6 +1327,11 @@ public class ManageApplications extends InstrumentedFragment
if (DEBUG) {
Log.d(TAG, "onRebuildComplete size=" + entries.size());
}
// Preload top visible icons of app list.
AppUtils.preloadTopIcons(mContext, entries,
mContext.getResources().getInteger(R.integer.config_num_visible_app_icons));
final int filterType = mAppFilter.getFilterType();
if (filterType == FILTER_APPS_POWER_ALLOWLIST
|| filterType == FILTER_APPS_POWER_ALLOWLIST_ALL) {
@@ -1480,8 +1489,7 @@ public class ManageApplications extends InstrumentedFragment
synchronized (entry) {
mState.ensureLabelDescription(entry);
holder.setTitle(entry.label, entry.labelDescription);
mState.ensureIcon(entry);
holder.setIcon(entry.icon);
updateIcon(holder, entry);
updateSummary(holder, entry);
updateSwitch(holder, entry);
holder.updateDisableView(entry.info);
@@ -1491,6 +1499,20 @@ public class ManageApplications extends InstrumentedFragment
holder.itemView.setOnClickListener(mManageApplications);
}
private void updateIcon(ApplicationViewHolder holder, AppEntry entry) {
final Drawable cachedIcon = AppUtils.getIconFromCache(entry);
if (cachedIcon != null && entry.mounted) {
holder.setIcon(cachedIcon);
} else {
ThreadUtils.postOnBackgroundThread(() -> {
final Drawable icon = AppUtils.getIcon(mContext, entry);
if (icon != null) {
ThreadUtils.postOnMainThread(() -> holder.setIcon(icon));
}
});
}
}
private void updateSummary(ApplicationViewHolder holder, AppEntry entry) {
switch (mManageApplications.mListType) {
case LIST_TYPE_NOTIFICATION: