今天客户提了一个bug说在短信添加附件,界面无法显示缩略图。接到这个bug我第一反应是缩略图生成失败了。
1.复现问题
1)在自己手上的版本无法复现该问题,再详细确认客户所处的分支,发现客户的分支与自己的不一致。
2)找与客户对应的分支的测试机器,复现只有当在Recent最近这个页面不能显示缩略图,其他页面都可以正常显示
2.通过Monitor—Hierarchy View工具查看Recent页面找到显示图片的icon的id为:icon_mime_lg.在DocumentUI搜索icon_mime_lg,定位到代码GridDocumentHolder.java
icon加载图片的调用是mIconHelper.load
3.查看IconHelper中load的方法
在如上方法加入debug信息,发现不管是在Recent页面还是其他页面都会走loadThumbnail,只有在Recent页面时showThumbnail为false,在其他页面为true.说明缩略图加载的,只是显示和不显示的问题,进一步分析发现在Recent页面时mThumbnailsEnabled未false,而在其他页面为true.而该值是通过public void setThumbnailsEnabled(boolean enabled)设置的
4,通过搜索setThumbnailsEnabled得知是在DirectoryFragment.java调用
5,查看ActivityManager中的
6.通过adb shell getprop ro.config.low_ram 返回true.
7,结论当设备配置ro.config.low_ram为true时,并且处于Recent页面,则不显示icon.App可以通过ActivityManager的isLowRamDevice API来判断当前设备是否是low ram。
1.复现问题
1)在自己手上的版本无法复现该问题,再详细确认客户所处的分支,发现客户的分支与自己的不一致。
2)找与客户对应的分支的测试机器,复现只有当在Recent最近这个页面不能显示缩略图,其他页面都可以正常显示
2.通过Monitor—Hierarchy View工具查看Recent页面找到显示图片的icon的id为:icon_mime_lg.在DocumentUI搜索icon_mime_lg,定位到代码GridDocumentHolder.java
@Override
public void bind(Cursor cursor, String modelId) {
assert(cursor != null);
mModelId = modelId;
mDoc.updateFromCursor(cursor, getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY));
mIconHelper.stopLoading(mIconThumb);
mIconMimeLg.animate().cancel();
mIconMimeLg.setAlpha(1f);
mIconThumb.animate().cancel();
mIconThumb.setAlpha(0f);
mIconHelper.load(mDoc, mIconThumb, mIconMimeLg, mIconMimeSm);
icon加载图片的调用是mIconHelper.load
3.查看IconHelper中load的方法
public void load(Uri uri, String mimeType, int docFlags, int docIcon, long docLastModified,
ImageView iconThumb, ImageView iconMime, @Nullable ImageView subIconMime) {
boolean loadedThumbnail = false;
final String docAuthority = uri.getAuthority();
final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
final boolean allowThumbnail = (mMode == MODE_GRID)
|| MimeTypes.mimeMatches(MimeTypes.VISUAL_MIMES, mimeType);
final boolean showThumbnail = supportsThumbnail && allowThumbnail && mThumbnailsEnabled;
if (showThumbnail) {
loadedThumbnail =
loadThumbnail(uri, docAuthority, docLastModified, iconThumb, iconMime);
}
final Drawable mimeIcon = getDocumentIcon(mContext, docAuthority,
DocumentsContract.getDocumentId(uri), mimeType, docIcon);
if (subIconMime != null) {
setMimeIcon(subIconMime, mimeIcon);
}
if (loadedThumbnail) {
hideImageView(iconMime);
} else {
// Add a mime icon if the thumbnail is not shown.
setMimeIcon(iconMime, mimeIcon);
hideImageView(iconThumb);
}
}
在如上方法加入debug信息,发现不管是在Recent页面还是其他页面都会走loadThumbnail,只有在Recent页面时showThumbnail为false,在其他页面为true.说明缩略图加载的,只是显示和不显示的问题,进一步分析发现在Recent页面时mThumbnailsEnabled未false,而在其他页面为true.而该值是通过public void setThumbnailsEnabled(boolean enabled)设置的
4,通过搜索setThumbnailsEnabled得知是在DirectoryFragment.java调用
boolean svelte = am.isLowRamDevice() && (mState.stack.isRecents());
mIconHelper.setThumbnailsEnabled(!svelte);
5,查看ActivityManager中的
/**
* Returns true if this is a low-RAM device. Exactly whether a device is low-RAM
* is ultimately up to the device configuration, but currently it generally means
* something in the class of a 512MB device with about a 800x480 or less screen.
* This is mostly intended to be used by apps to determine whether they should turn
* off certain features that require more RAM.
*/
public boolean isLowRamDevice() {
return isLowRamDeviceStatic();
}
/** @hide */
public static boolean isLowRamDeviceStatic() {
return RoSystemProperties.CONFIG_LOW_RAM ||
(Build.IS_DEBUGGABLE && DEVELOPMENT_FORCE_LOW_RAM);
}
6.通过adb shell getprop ro.config.low_ram 返回true.
7,结论当设备配置ro.config.low_ram为true时,并且处于Recent页面,则不显示icon.App可以通过ActivityManager的isLowRamDevice API来判断当前设备是否是low ram。