編輯:關於Android編程
Android實際開發中,在加載大量圖片的時候,比如ViewPager、GridView、ListView中,加載了大量的比較大圖片就容易出現OOM(內存溢出)的異常,這是因為一個應用的最大內存使用只有16M,超過了這個值,就會出現OOM。所以我們實際開發中,要想避免OOM出現就要對相應的圖片進行壓縮處理。
本文即使用了BitmapFactory和BitmapFactory.Option這兩個類,對圖片進行相應的尺寸壓縮處理。經測試,成功解決了未壓縮圖片之前出現的OOM異常。
實現效果圖:
本Demo使用的圖片大小為2M左右(壓縮以前)。
我壓縮圖片之前:
我這裡將壓縮的代碼注釋掉了:

運行結果:

進行壓縮處理後的圖片:
壓縮後圖片大小為:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140718/2014071809444262.jpg" alt="\">
大約為98KB
運行結果:

源代碼:

布局文件:
activity_main:
MainActivity:
package com.android_bitmapcompressdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView listView;
private MyAdapter adapter;
private int[] items = new int[] { R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
adapter = new MyAdapter(this, items);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
ListView適配器:MyAdapter:
package com.android_bitmapcompressdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private int[] items = new int[] {};
private Context context;
private String TAG = "zhongyao";
private Bitmap bitmap = null;
public MyAdapter(Context context, int[] items) {
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int position) {
return items[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
holder.textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(
context.getResources(), R.drawable.pc, 100, 100);
Log.d(TAG, "壓縮之後的圖片大小為:" + bitmap.getByteCount());
holder.imageView.setImageBitmap(bitmap);
holder.textView.setText("圖片"+position);
return convertView;
}
class ViewHolder {
ImageView imageView;
TextView textView;
}
}
package com.android_bitmapcompressdemo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapCompressTools {
public static Bitmap decodeSampledBitmapFromResource(Resources res,
int resId, int reqWidth, int reqHeight) {
// 給定的BitmapFactory設置解碼的參數
final BitmapFactory.Options options = new BitmapFactory.Options();
// 從解碼器中獲取原始圖片的寬高,這樣避免了直接申請內存空間
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// 壓縮完後便可以將inJustDecodeBounds設置為false了。
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/**
* 指定圖片的縮放比例
*
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 原始圖片的寬、高
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
// if (height > reqHeight || width > reqWidth) {
// //這裡有兩種壓縮方式,可供選擇。
// /**
// * 壓縮方式二
// */
// // final int halfHeight = height / 2;
// // final int halfWidth = width / 2;
// // while ((halfHeight / inSampleSize) > reqHeight
// // && (halfWidth / inSampleSize) > reqWidth) {
// // inSampleSize *= 2;
// // }
//
/**
* 壓縮方式一
*/
// 計算壓縮的比例:分為寬高比例
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
// }
return inSampleSize;
}
}
源代碼已上傳到資源中,可到我的資源中下載。
Android智能指針分析(sp、wp)
在Android native編寫代碼時,會經常接觸到sp、wp,sp並不是smart pointer的意思,而是strong point;wp就是weak point
[Android] 更改關聯的源碼路徑
右擊選中工程 → Java Build Path → Libraries → Android 4.1.2 → 點開android.jar → 選中Source attac
Android 安全加密:對稱加密詳解
Android安全加密專題文章索引 Android安全加密:對稱加密 Android安全加密:非對稱加密 Android安全加密:消息摘要Message D
Android控件使用 — 12個Material Design風格控件的使用
1、AppBarLayout、ToolBarAppBarLayout 是繼承LinerLayout實現的一個ViewGroup容器組件,它是為了Material Desi