[英]Android: outOfMemoryError with bitmaps in Gallery
我有一個應用程序,可以從服務器下載圖像,將圖像存儲在sd卡上,然后以幻燈片形式顯示給用戶。 該應用程序具有用戶可以查看的許多不同的幻燈片。 我的問題是,在查看幾個圖庫后,出現內存不足錯誤。 我已經做了大量的谷歌搜索工作,並且閱讀了大約20遍羅曼·蓋伊(Romain Guy)的《避免內存泄漏》一文。 我嘗試復制他的unbindDrawables()方法,但無法在Gallery對象上調用butRemoveAllViews()。 我也嘗試過在所有位圖上調用recycle(),但是當我在適配器內的位圖上進行調用時,應用程序在打開圖像庫后立即引發錯誤。 我還嘗試過重新編碼幻燈片,以便在適配器之外創建所有位圖,然后將它們作為數組傳遞給我-這使我可以遍歷位圖數組,並在幻燈片的onDestroy方法中對每個位圖調用recycle()活動-但這實際上似乎使泄漏情況變得越來越糟。
這是我的幻燈片活動的代碼:
public class Slideshow extends Activity {
static String galleryId;
public static final int MSG_DOWNLOADED = 0;
static Handler handler;
static Gallery g;
static ArrayList<String> filePaths;
static String subFolder;
static ArrayList<String> imageToGet;
static LinearLayout pb;
static boolean firstTime = true;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slideshow);
Context context = getApplicationContext();
Bundle extras = getIntent().getExtras();
if(extras != null){
galleryId = extras.getString("galleryId");
}
pb = (LinearLayout) findViewById(R.id.progress);
handler = new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what){
case MSG_DOWNLOADED:
g.setAdapter(new SlideshowAdapter(getApplicationContext(), R.id.gallery, filePaths));
pb.setVisibility(8);
if(firstTime){
Thread images = new Thread(){
public void run(){
ImageGallery gallery = XMLParser.getGalleryById(galleryId, false, getApplicationContext());
ArrayList<String> imageURLs = gallery.getImageURLs();
String subFolder = "gallery"+galleryId+"/";
getImages(imageURLs, subFolder, false);
}
};
images.start();
firstTime = false;
}
break;
}
}
};
ImageGallery gallery = XMLParser.getGalleryById(galleryId, false, context);
filePaths = gallery.getFilePaths();
ArrayList<String> imageURLs = gallery.getImageURLs();
subFolder = "gallery"+galleryId+"/";
g = (Gallery) findViewById(R.id.gallery);
if(filePaths.size() > 0){
String filePath = filePaths.get(0);
String url = imageURLs.get(0);
imageToGet = new ArrayList<String>();
imageToGet.add(url);
if(filePaths.size() == 1 ){
File file = new File(filePath);
if(!file.exists()){
Thread getFirstImage = new Thread(){
public void run(){
Log.d("ClubSlideshow getting only image", ""+imageToGet.get(0));
getImages(imageToGet, subFolder, false);
handler.sendEmptyMessage(MSG_DOWNLOADED);
}
};
getFirstImage.start();
}
}else if(filePaths.size()>1){
String filePath2 = filePaths.get(1);
String url2 = imageURLs.get(1);
File file = new File(filePath);
File file2 = new File(filePath2);
imageToGet.add(url2);
if(!file.exists()||!file2.exists()){
Thread getFirstImage = new Thread(){
public void run(){
getImages(imageToGet, subFolder, false);
handler.sendEmptyMessage(MSG_DOWNLOADED);
}
};
getFirstImage.start();
}
}
}
}
public void getImages(ArrayList<String> imageURLs, String subFolder, boolean force){
DataCache.downloadFromUrlArray(imageURLs, subFolder, force, getApplicationContext());
}
public class ImageThread implements Runnable{
public ImageThread(ArrayList<String> imageURLs, String subFolder, Boolean force){
getImages(imageURLs, subFolder, force);
}
public void run(){
}
}
@Override
protected void onDestroy(){
super.onDestroy();
g.setAdapter(null);
}
}
這是我的SlideshowAdapter類的代碼:
public class SlideshowAdapter extends ArrayAdapter<String> {
int mGalleryItemBackground;
private Context mContext;
private ArrayList<String> images = new ArrayList<String>();
Bitmap bMap;
String filePath;
File file;
ImageView i;
public SlideshowAdapter(Context c, int resourceId, ArrayList<String> objects){
super(c, resourceId, objects);
this.mContext = c;
this.images = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView !=null){
i = (ImageView) convertView;
}else{
i = new ImageView(mContext);
}
filePath = mContext.getFilesDir()+"/"+images.get(position);
file = new File(filePath);
if(file.exists()){
bMap = BitmapFactory.decodeFile(filePath);
i.setImageBitmap(bMap);
}
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
return i;
}
}
誰能看到導致我出現內存問題的原因嗎?
實際上有幾個問題:
getView
方法convertView為null時,都會看到此錯誤 您可以嘗試使用scaledBitmap減少內存使用量
if(file.exists()){
bMap = BitmapFactory.decodeFile(filePath);
i.setImageBitmap(bMap);
}
至
if(file.exists()){
bMap = BitmapFactory.decodeFile(filePath);
bMap = Bitmap.createScaledBitmap(bMap, 100, 100, true);
i.setImageBitmap(bMap);
}
嘗試將圖像存儲在SD卡或設備內存中,以避免此問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.