package me.xiaopan.sketch; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Build; import android.os.Environment; import android.text.format.Formatter; import java.io.File; import java.util.Arrays; import java.util.List; import me.xiaopan.sketch.drawable.RefDrawable; import me.xiaopan.sketch.feature.large.Tile; import me.xiaopan.sketch.process.ImageProcessor; import me.xiaopan.sketch.request.DisplayRequest; import me.xiaopan.sketch.request.DownloadRequest; import me.xiaopan.sketch.request.LoadRequest; import me.xiaopan.sketch.util.SketchUtils; // TODO: 2017/4/15 改名SketchExceptionTracker public class SketchMonitor implements Identifier { protected String logName = "SketchMonitor"; private Context context; public SketchMonitor(Context context) { context = context.getApplicationContext(); this.context = context; } /** * 安装磁盘缓存失败 * * @param e NoSpaceException:空间不足; * UnableCreateDirException:无法创建缓存目录; * UnableCreateFileException:无法在缓存目录中创建文件 * @param cacheDir 默认的缓存目录 */ public void onInstallDiskCacheError(Exception e, File cacheDir) { SLog.e(logName, "onInstallDiskCacheError. %s: %s. SDCardState: %s. cacheDir: %s", e.getClass().getSimpleName(), e.getMessage(), Environment.getExternalStorageState(), cacheDir.getPath()); } /** * 解码GIF图片失败 * * @param throwable UnsatisfiedLinkError或ExceptionInInitializerError:找不到对应到的so文件 * @param request 请求 * @param outWidth 图片原始宽 * @param outHeight 图片原始高 * @param outMimeType 图片类型 */ public void onDecodeGifImageError(Throwable throwable, LoadRequest request, int outWidth, int outHeight, String outMimeType) { if (throwable instanceof UnsatisfiedLinkError || throwable instanceof ExceptionInInitializerError) { SLog.e("Didn't find “libpl_droidsonroids_gif.so” file, " + "unable to process the GIF images. If you need to decode the GIF figure " + "please go to “https://github.com/xiaopansky/sketch” " + "download “libpl_droidsonroids_gif.so” file and put in your project"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { SLog.e("abis=%s", Arrays.toString(Build.SUPPORTED_ABIS)); } else { SLog.e("abi1=%s, abi2=%s", Build.CPU_ABI, Build.CPU_ABI2); } } SLog.e(logName, "onDecodeGifImageError. outWidth=%d, outHeight=%d + outMimeType=%s. %s", outWidth, outHeight, outMimeType, request.getKey()); } /** * 解码普通图片失败 * * @param throwable OutOfMemoryError:内存溢出 * @param request 请求 * @param outWidth 图片原始宽 * @param outHeight 图片原始高 * @param outMimeType 图片类型 */ public void onDecodeNormalImageError(Throwable throwable, LoadRequest request, int outWidth, int outHeight, String outMimeType) { if (throwable instanceof OutOfMemoryError) { long maxMemory = Runtime.getRuntime().maxMemory(); long freeMemory = Runtime.getRuntime().freeMemory(); long totalMemory = Runtime.getRuntime().totalMemory(); String maxMemoryFormatted = Formatter.formatFileSize(context, maxMemory); String freeMemoryFormatted = Formatter.formatFileSize(context, freeMemory); String totalMemoryFormatted = Formatter.formatFileSize(context, totalMemory); SLog.e(logName, "OutOfMemoryError. appMemoryInfo: maxMemory=%s, freeMemory=%s, totalMemory=%s", maxMemoryFormatted, freeMemoryFormatted, totalMemoryFormatted); } SLog.e(logName, "onDecodeNormalImageError. outWidth=%d, outHeight=%d, outMimeType=%s. %s", outWidth, outHeight, outMimeType, request.getKey()); } /** * 处理图片失败 * * @param e OutOfMemoryError:内存溢出 * @param imageUri 图片uri * @param processor 所使用的处理器 */ public void onProcessImageError(Throwable e, String imageUri, ImageProcessor processor) { if (e instanceof OutOfMemoryError) { long maxMemory = Runtime.getRuntime().maxMemory(); long freeMemory = Runtime.getRuntime().freeMemory(); long totalMemory = Runtime.getRuntime().totalMemory(); String maxMemoryFormatted = Formatter.formatFileSize(context, maxMemory); String freeMemoryFormatted = Formatter.formatFileSize(context, freeMemory); String totalMemoryFormatted = Formatter.formatFileSize(context, totalMemory); SLog.d("OutOfMemoryError. appMemoryInfo: maxMemory=%s, freeMemory=%s, totalMemory=%s", maxMemoryFormatted, freeMemoryFormatted, totalMemoryFormatted); } SLog.e(logName, "onProcessImageError. imageUri: %s. processor: %s", imageUri, processor.getKey()); } /** * 下载出现错误 * * @param request 出错的下载请求 * @param throwable 异常 */ public void onDownloadError(@SuppressWarnings("UnusedParameters") DownloadRequest request, @SuppressWarnings("UnusedParameters") Throwable throwable) { } /** * 碎片排序错误,Java7的排序算法在检测到A大于B, B小于C, 但是A小于等于C的时候就会抛出异常 * * @param e 异常 * @param tileList 碎片列表 * @param useLegacyMergeSort 当前是否使用旧的排序算法 */ public void onTileSortError(@SuppressWarnings("UnusedParameters") IllegalArgumentException e, List<Tile> tileList, @SuppressWarnings("UnusedParameters") boolean useLegacyMergeSort) { String legacy = useLegacyMergeSort ? "useLegacyMergeSort. " : ""; SLog.w(logName, "onTileSortError. %s%s", legacy, SketchUtils.tileListToString(tileList)); } /** * 在即将显示时发现Bitmap被回收 */ public void onBitmapRecycledOnDisplay(DisplayRequest request, RefDrawable refDrawable) { SLog.w(logName, "onBitmapRecycledOnDisplay. imageUri=%s, drawable=%s", request.getUri(), refDrawable.getInfo()); } /** * 在BitmapRegionDecoder中使用inBitmap是发生异常 * * @param imageUri 图片url * @param imageWidth 图片宽 * @param imageHeight 图片高 * @param srcRect 读取区域 * @param inSampleSize 缩放比例 * @param inBitmap 复用的inBitmap */ public void onInBitmapExceptionForRegionDecoder(String imageUri, int imageWidth, int imageHeight, Rect srcRect, int inSampleSize, Bitmap inBitmap) { SLog.w(logName, "onInBitmapExceptionForRegionDecoder. imageUri=%s, imageSize=%dx%d, srcRect=%s, inSampleSize=%d, inBitmapSize=%dx%d, inBitmapByteCount=%d", imageUri, imageWidth, imageHeight, srcRect.toString(), inSampleSize, inBitmap.getWidth(), inBitmap.getHeight(), SketchUtils.getByteCount(inBitmap)); } /** * 在BitmapFactory中使用inBitmap是发生异常 * * @param imageUri 图片url * @param imageWidth 图片宽 * @param imageHeight 图片高 * @param inSampleSize 缩放比例 * @param inBitmap 复用的inBitmap */ public void onInBitmapException(String imageUri, int imageWidth, int imageHeight, int inSampleSize, Bitmap inBitmap) { SLog.w(logName, "onInBitmapException. imageUri=%s, imageSize=%dx%d, inSampleSize=%d, inBitmapSize=%dx%d, inBitmapByteCount=%d", imageUri, imageWidth, imageHeight, inSampleSize, inBitmap.getWidth(), inBitmap.getHeight(), SketchUtils.getByteCount(inBitmap)); } @Override public String getKey() { return logName; } }