Имам приложение, което изтегля изображения от сървър, съхранява ги на sd картата и след това ги показва на потребителя като слайдшоу. Приложението има няколко различни слайдшоута, които потребителят може да гледа. Проблемът ми е, че след като прегледам няколко галерии, получавам грешка за липса на памет. Направих доста гугъл и прочетох статията на Romain Guy за избягване на изтичане на памет около 20 пъти. Опитах се да копирам неговия метод unbindDrawables(), но методът but removeAllViews() не може да бъде извикан на обекти на галерия. Също така се опитах да извикам recycle() на всички растерни изображения, които мога, но когато го направя на растерното изображение в адаптера, приложението извежда грешка веднага щом отворя галерия с изображения. Също така се опитах да прекодирам слайдшоуто, така че да създам всички растерни изображения извън адаптера и след това да ги предам като масив — това ми позволява да превъртя своя масив с растерни изображения и да извикам recycle() на всеки от тях в метода onDestroy в слайдшоуто активност - но това всъщност изглежда влошава изтичането, а не подобрява.
Ето кода за моята дейност в слайдшоуто:
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;
}
}
Може ли някой да види какво може да причинява проблемите ми с паметта?