編輯:關於Android編程
大家好,今天給大家分享的是解決解析圖片的出現oom的問題,我們可以用BitmapFactory這裡的各種Decode方法,如果圖片很小的話,不會出現oom,但是當圖片很大的時候
就要用BitmapFactory.Options這個東東了,Options裡主要有兩個參數比較重要.
options.inJustDecodeBounds = false/true; //圖片壓縮比例. options.inSampleSize = ssize;
我們去解析一個圖片,如果太大,就會OOM,我們可以設置壓縮比例inSampleSize,但是這個壓縮比例設置多少就是個問題,所以我們解析圖片可以分為倆個步驟,第一步就是
獲取圖片的寬高,這裡要設置Options.inJustDecodeBounds=true,這時候decode的bitmap為null,只是把圖片的寬高放在Options裡,然後第二步就是設置合適的壓縮比例inSampleSize,這時候獲得合適的Bitmap.這裡我畫了簡單的流程圖,如下:
為了讓大家更容易理解,我這裡做了一個簡單的demo,主要功能就是一個界面裡有個ImageView,點擊ImageView的時候,進入本地相冊,選擇一個圖片的時候,ImageView控件顯示選擇的圖片。Demo的步驟如下:
第一步新建一個Android工程命名為ImageCacheDemo.目錄結構如下:
第二步新建一個ImageCacheUtil.Java工具類,代碼如下:
package com.tutor.oom;
import java.io.InputStream;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
/**
* @author frankiewei.
* 工具類.
*/
public class ImageCacheUtil {
/**
* 獲取合適的Bitmap平時獲取Bitmap就用這個方法吧.
* @param path 路徑.
* @param data byte[]數組.
* @param context 上下文
* @param uri uri
* @param target 模板寬或者高的大小.
* @param width 是否是寬度
* @return
*/
public static Bitmap getResizedBitmap(String path, byte[] data,
Context context,Uri uri, int target, boolean width) {
Options options = null;
if (target > 0) {
Options info = new Options();
//這裡設置true的時候,decode時候Bitmap返回的為空,
//將圖片寬高讀取放在Options裡.
info.inJustDecodeBounds = false;
decode(path, data, context,uri, info);
int dim = info.outWidth;
if (!width)
dim = Math.max(dim, info.outHeight);
int ssize = sampleSize(dim, target);
options = new Options();
options.inSampleSize = ssize;
}
Bitmap bm = null;
try {
bm = decode(path, data, context,uri, options);
} catch(Exception e){
e.printStackTrace();
}
return bm;
}
/**
* 解析Bitmap的公用方法.
* @param path
* @param data
* @param context
* @param uri
* @param options
* @return
*/
public static Bitmap decode(String path, byte[] data, Context context,
Uri uri, BitmapFactory.Options options) {
Bitmap result = null;
if (path != null) {
result = BitmapFactory.decodeFile(path, options);
} else if (data != null) {
result = BitmapFactory.decodeByteArray(data, 0, data.length,
options);
} else if (uri != null) {
//uri不為空的時候context也不要為空.
ContentResolver cr = context.getContentResolver();
InputStream inputStream = null;
try {
inputStream = cr.openInputStream(uri);
result = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
/**
* 獲取合適的sampleSize.
* 這裡就簡單實現都是2的倍數啦.
* @param width
* @param target
* @return
*/
private static int sampleSize(int width, int target){
int result = 1;
for(int i = 0; i < 10; i++){
if(width < target * 2){
break;
}
width = width / 2;
result = result * 2;
}
return result;
}
}
第三步:修改ImageCacheDemoActivity.java代碼如下:
package com.tutor.oom;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
/**
* @author frankiewei.
* 解決圖片普通OOM的Demo.
*/
public class ImageCacheDemoActivity extends Activity {
/**
* 顯示圖片的ImageView.
*/
private ImageView mImageView;
/**
* 打開本地相冊的requestcode.
*/
public static final int OPEN_PHOTO_REQUESTCODE = 0x1;
/**
* 圖片的target大小.
*/
private static final int target = 400;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupViews();
}
private void setupViews(){
mImageView = (ImageView)findViewById(R.id.imageview);
mImageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
openPhotos();
}
});
}
/**
* 打開本地相冊.
*/
private void openPhotos() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"image/*");
startActivityForResult(intent, OPEN_PHOTO_REQUESTCODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case OPEN_PHOTO_REQUESTCODE:
if(resultCode == RESULT_OK){
//如果用這個方法,Options為null時候,就是默認decode會出現oom哦.
//Bitmap bm = ImageCacheUtil.decode(null, null,
// ImageCacheDemoActivity.this, data.getData(), null);
//這裡調用這個方法就不會oom.屌絲們就用這個方法吧.
Bitmap bm = ImageCacheUtil.getResizedBitmap(null, null,
ImageCacheDemoActivity.this, data.getData(), target, false);
mImageView.setImageBitmap(bm);
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
其中main.xml布局代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ImageView
android:id="@+id/imageview"
android:layout_width="400px"
android:layout_height="400px"
android:src="@drawable/ic_launcher"
/>
</LinearLayout>
第四步運行上述工程,效果如下:

從本地相冊選擇顯示。用了getRsizedBitmap()方法,圖片很大不會oom.
運用默認的decode方法就會oom。
OK,今天就講到這裡,以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
原文鏈接:http://blog.csdn.net/android_tutor/article/details/8099918
VoLTE高清語音通話支持哪些手機
隨著蘋果向iPhone6以上的機型推送VoLTE高清語音通話運營商配置更新文件,更多網友開始關注這一新的語音技術,那麼現在國內有哪些手機是支持VoLTE高清
Android View 事件分發機制源碼詳解(ViewGroup篇)
前言我們在學習View的時候,不可避免會遇到事件的分發,而往往遇到的很多滑動沖突的問題都是由於處理事件分發時不恰當所造成的。因此,深入了解View事件分發機制的原理,對於
Android WebView上實現JavaScript與Java交互
其實webview加載資源的速度並不慢,但是如果資源多了,當然就很慢。圖片、css 、js 、html這些資源每個大概需要10-200ms ,一般都是30ms就ok了。不
Android Studio vs Eclipse:你需要知道的那些事
用Android Studio開發前,你需要知道我寫的這個指引裡,包含了一些當你要把Eclipse項目轉到Andorid Studio前需要知道的基本信息。