参考书籍Android移动性能实战
a、单例很容易理解,我们都知道单例的生命周期跟随应用的生命周期,如果单例持有了Activity或Fragment的引用,那就会引起内存泄漏。
b、内部类引起的内存泄漏,成员内部类, 局部内部类、 匿名内部类。 会有对外部类的引用。这样内部类中耗时操作在用户频繁退出重启APP相关Activity时很容易导致内存泄漏。
以上案例可参考http://blog.csdn.net/sinat_31057219/article/details/74533647总结的比较细,就不再详述了
一般我们获取一个系统服务会直接在Activity中getSystemService(Context.WIFI_SERVICE),但是这样相当于这个服务持有了外部Activity的引用,如果在服务内部发生异常,就无法释放这个引用了。所以我们获取服务要使用:getApplicationContext().getSystemService(Context.WIFI_SERVICE),这样就不会产生泄漏了。
同时我们要注意以下几点
- 在使用系统服务时尽量避免使用界面的Context
- 提供异步工作的服务,一定要注意回调函数、handle、oberserve等通知类型的对象的注册与反注册的成对出现
参考文章https://www.jianshu.com/p/3e8f7dbb0dc7
a、进程方式解决:这也是腾讯采用的方式即为加载WebView的界面开启新进程,在该页面退出之后关闭这个进程。
b、处理onDestory
@Override
protected void onDestroy() {
if( mWebView!=null) {
// 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
// destory()
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.stopLoading();
// 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.clearView();
mWebView.removeAllViews();
mWebView.destroy();
}
super.on Destroy();
}
解决多图片在内存常驻问题。
适用场景:在对图片显示质量要求不高的缩略图,或高清图缩小时使用.
使用方法:
BitmapFactory.Options options = new BitmapFactory.Options();
options1.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0 , data.length, options);
小常识
ALPHA_8 代表8位Alpha位图
ARGB_4444 代表16位ARGB位图
ARGB_8888 代表32位ARGB位图
RGB_565 代表8位RGB位图位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真。
参考文章https://developer.xamarin.com/recipes/android/resources/general/load_large_bitmaps_efficiently/
简单来说就是三步
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
解析
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}