2012-07-24 5 views
0

나는 이미지를 배경으로로드하기 위해 imageLoader 클래스를 사용하고 있는데, 그 후에 에뮬레이터에서 이미지를 설정하고있다. 기기에서 lazy downloaded 이미지가 표시되지 않습니다.게으른 이미지 로더가 기기에서 작동하지 않습니까?

private void queuePhoto(String url, Activity activity, ImageView imageView) 
{ 
    photosQueue.Clean(imageView); 
    PhotoToLoad p=new PhotoToLoad(url, imageView); 
    synchronized(photosQueue.photosToLoad) 
    { 
     photosQueue.photosToLoad.push(p); 
     photosQueue.photosToLoad.notifyAll(); 
    } 
    (photoLoaderThread.getState()==Thread.State.NEW) 
    photoLoaderThread.start(); 
} 
+0

지연 이미지가 에뮬레이터와 잘 작동하지만 이미지가 저장되지 않는 장치가 있습니다. –

+0

어디에서 이미지 파일을 저장하고 있습니까? 내부 디렉토리 또는 SD 카드? 나는 잘 작동한다. – RobGThai

+0

구현을 볼 수 있습니까 –

답변

0

여기 내 버전은 ImageLoader입니다. 진행률 표시 줄이있는 모든 ImageView를 동행합니다. 그런 다음 애니메이션이 전환에 적용되었습니다. SD 카드 캐싱 옵션도 제거했습니다. 내 수정본 중 가장 남은 부분을 볼 수 있습니다.

/* 
* Copyright (c)2012 Poohdish Rattanavijai 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package com.robgthai.lib.util; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.util.HashMap; 
import java.util.Stack; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.util.Log; 
import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.AnimationUtils; 
import android.widget.ImageView; 
import android.widget.ProgressBar; 

import com.robgthai.lib.R; 

/** 
* This class help handling the Lazyload of the image from given URL 
* @author Poohdish Rattanavijai 
* 
*/ 
public class ImageLoader { 
    private static final String TAG = ImageLoader.class.getSimpleName(); 
    private static final int LOG_LEVEL = (HelperUtil.FORCE_EVERY_LOG? Log.DEBUG: Log.INFO); 
    //the simplest in-memory cache implementation. This should be replaced with something like SoftReference or BitmapOptions.inPurgeable(since 1.6) 
    private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>(); 
    private File cacheDir; 
    private Context context; 

    final int stub_id=R.drawable.ic_refresh; // Default icon to display before the image finish loaded 

    public ImageLoader(Context context){ 
     //Make the background thead low priority. This way it will not affect the UI performance 
     photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); 
     this.context = context; 
     cacheDir=new File(context.getCacheDir(),"LazyList"); 

     //Find the dir to save cached images 
//  if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) 
//   cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList"); 
//  else 
//  cacheDir=context.getCacheDir(); 
     if(!cacheDir.exists()) 
      cacheDir.mkdirs(); 
    } 

    /** 
    * Method for lazy-loading images 
    * @param url URL of the image 
    * @param activity Activity context, currently unused 
    * @param imageView ImageView to display the image 
    * @param progressBar ProgressBar for displaying while the image is being load 
    */ 
    public void DisplayImage(String url, Activity activity, ImageView imageView, ProgressBar progressBar) 
    { 
     if(cache.containsKey(url)) //If image is already in the cache 
      imageView.setImageBitmap(cache.get(url)); 
     else 
     { 
      queuePhoto(url, activity, imageView, progressBar); 
      imageView.setImageResource(stub_id); 
     }  
    } 

    /** 
    * Method for lazy-loading images with the image sliding in from the left replacing the progress bar 
    * @param url URL of the image 
    * @param context Activity context, currently unused 
    * @param imageView ImageView to display the image 
    * @param progressBar ProgressBar for displaying while the image is being load 
    */ 
    public void DisplayImage(String url, Context context, ImageView imageView, ProgressBar progressBar) 
    { 
     if(cache.containsKey(url)){ 
      if(LOG_LEVEL <= Log.DEBUG)Log.d(TAG, "Found in cache: " + url + "[" + cache.get(url) + "]"); 
      imageView.setImageBitmap(cache.get(url)); 

      Animation exitAnim = AnimationUtils.loadAnimation(ImageLoader.this.context, R.anim.list_image_slide_left_exit); 
      exitAnim.setFillAfter(true); 
      exitAnim.setFillEnabled(true); 

      Animation enterAnim = AnimationUtils.loadAnimation(ImageLoader.this.context, R.anim.list_image_slide_left_enter); 
      enterAnim.setFillAfter(true); 
      enterAnim.setFillEnabled(true); 
      progressBar.setVisibility(View.GONE); 
      imageView.setVisibility(View.VISIBLE); 

      progressBar.startAnimation(exitAnim); 
      imageView.startAnimation(enterAnim); 
//   if(bitmap!=null){ 
//    imageView.setImageBitmap(bitmap); 
//    if(null != progress){ 
//     progress.startAnimation(exitAnim); 
//     progress.setVisibility(View.GONE); 
//    } 
//    imageView.startAnimation(enterAnim); 
////    imageView.setVisibility(View.VISIBLE); 
//   }else{ 
//    if(null != progress){ 
//     progress.startAnimation(enterAnim); 
////     progress.setVisibility(View.VISIBLE); 
//     imageView.setVisibility(View.GONE); 
//    }else{ 
//     imageView.setImageResource(stub_id); 
//     imageView.startAnimation(enterAnim); 
////     imageView.setVisibility(View.VISIBLE); 
//    } 
//   } 
     }else 
     { 
      queuePhoto(url, context, imageView, progressBar); 
      imageView.setImageResource(stub_id); 
     }  
    } 

    /** 
    * Queue the image to download 
    * @param url 
    * @param context 
    * @param imageView 
    * @param progressBar 
    */ 
    private void queuePhoto(String url, Context context, ImageView imageView, ProgressBar progressBar) 
    { 
     //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
     photosQueue.Clean(imageView); 
     PhotoToLoad p= null; 
     if(null != progressBar){ 
      p = new PhotoToLoad(url, imageView, progressBar); 
     }else{ 
      p = new PhotoToLoad(url, imageView); 
     } 
     synchronized(photosQueue.photosToLoad){ 
      photosQueue.photosToLoad.push(p); 
      photosQueue.photosToLoad.notifyAll(); 
     } 

     //start thread if it's not started yet 
     if(photoLoaderThread.getState()==Thread.State.NEW) 
      photoLoaderThread.start(); 
    } 

    /** 
    * Queue the image to download 
    * @param url 
    * @param context 
    * @param imageView 
    * @param progressBar 
    */  
    private void queuePhoto(String url, Activity activity, ImageView imageView, ProgressBar progressBar) 
    { 
     //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
     photosQueue.Clean(imageView); 
     PhotoToLoad p= null; 
     if(null != progressBar){ 
      p = new PhotoToLoad(url, imageView, progressBar); 
     }else{ 
      p = new PhotoToLoad(url, imageView); 
     } 
     synchronized(photosQueue.photosToLoad){ 
      photosQueue.photosToLoad.push(p); 
      photosQueue.photosToLoad.notifyAll(); 
     } 

     //start thread if it's not started yet 
     if(photoLoaderThread.getState()==Thread.State.NEW) 
      photoLoaderThread.start(); 
    } 

    /** 
    * Load image into the view preferably from Cache, otherwise url. 
    * @param url 
    * @return 
    */ 
    private Bitmap getBitmap(String url) 
    { 
     //identify images by hashcode. Not a perfect solution, good for the demo. 
     String filename=String.valueOf(url.hashCode()); 
     File f=new File(cacheDir, filename); 

     //from cache 
     Bitmap b = decodeFile(f); 
     if(LOG_LEVEL <= Log.DEBUG)Log.d(TAG, "Looking for Image in cache"); 
     if(b!=null){ 
      if(LOG_LEVEL <= Log.DEBUG)Log.d(TAG, "Image found"); 
      return b; 
     } 

     //from web 
     try { 
      if(LOG_LEVEL <= Log.DEBUG)Log.d(TAG, "Image not found, download from: " + url); 
      Bitmap bitmap=null; 
      InputStream is=new URL(url).openStream(); 
      OutputStream os = new FileOutputStream(f); 
      HelperUtil.CopyStream(is, os); 
      os.close(); 
      bitmap = decodeFile(f); 
      return bitmap; 
     } catch (Exception ex){ 
      ex.printStackTrace(); 
      return null; 
     } 
    } 

    //decodes image and scales it to reduce memory consumption 
    private Bitmap decodeFile(File f){ 
     try { 
      //decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

      //Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE=70; 
      int width_tmp=o.outWidth, height_tmp=o.outHeight; 
      int scale=1; 
      while(true){ 
       if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
        break; 
       width_tmp/=2; 
       height_tmp/=2; 
       scale*=2; 
      } 

      //decode with inSampleSize 
      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize=scale; 
      return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     } catch (FileNotFoundException e) {} 
     return null; 
    } 

    //Task for the queue 
    private class PhotoToLoad 
    { 
     public String url; 
     public ImageView imageView; 
     public ProgressBar progress; 
     public PhotoToLoad(String u, ImageView i, ProgressBar p){ 
      url=u; 
      imageView=i; 
      progress = p; 
     } 
     public PhotoToLoad(String u, ImageView i){ 
      url=u; 
      imageView=i; 
     } 
    } 

    PhotosQueue photosQueue=new PhotosQueue(); 

    public void stopThread() 
    { 
     photoLoaderThread.interrupt(); 
    } 

    //stores list of photos to download 
    class PhotosQueue 
    { 
     private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>(); 

     //removes all instances of this ImageView 
     public void Clean(ImageView image) 
     { 
      for(int j=0 ;j<photosToLoad.size();){ 
       if(photosToLoad.get(j).imageView==image) 
        photosToLoad.remove(j); 
       else 
        ++j; 
      } 
     } 
    } 

    /** 
    * Controller of the image loader 
    * @author poohdishr 
    * 
    */ 
    class PhotosLoader extends Thread { 
     public void run() { 
      try { 
       while(true) 
       { 
        //thread waits until there are any images to load in the queue 
        if(photosQueue.photosToLoad.size()==0) 
         synchronized(photosQueue.photosToLoad){ 
          photosQueue.photosToLoad.wait(); 
         } 
        if(photosQueue.photosToLoad.size()!=0) 
        { 
         PhotoToLoad photoToLoad; 
         synchronized(photosQueue.photosToLoad){ 
          photoToLoad=photosQueue.photosToLoad.pop(); 
         } 
         Bitmap bmp=getBitmap(photoToLoad.url); 
         cache.put(photoToLoad.url, bmp); 
         Object tag=photoToLoad.imageView.getTag(); 
         if(tag!=null && ((String)tag).equals(photoToLoad.url)){ 
          BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView, photoToLoad.progress); 
          Activity a=(Activity)photoToLoad.imageView.getContext(); 
          a.runOnUiThread(bd); 
         } 
        } 
        if(Thread.interrupted()) 
         break; 
       } 
      } catch (InterruptedException e) { 
       //allow thread to exit 
      } 
     } 
    } 

    PhotosLoader photoLoaderThread=new PhotosLoader(); 

    //Used to display bitmap in the UI thread 
    class BitmapDisplayer implements Runnable 
    { 
     Bitmap bitmap; 
     ImageView imageView; 
     ProgressBar progress; 
     public BitmapDisplayer(Bitmap b, ImageView i, ProgressBar p){bitmap=b;imageView=i;progress=p;} 
     public void run() 
     { 
      Animation exitAnim = AnimationUtils.loadAnimation(ImageLoader.this.context, R.anim.list_image_slide_left_exit); 
      exitAnim.setFillAfter(true); 
      exitAnim.setFillEnabled(true); 

      Animation enterAnim = AnimationUtils.loadAnimation(ImageLoader.this.context, R.anim.list_image_slide_left_enter); 
      enterAnim.setFillAfter(true); 
      enterAnim.setFillEnabled(true); 
      if(bitmap!=null){ 
       imageView.setImageBitmap(bitmap); 
       if(null != progress){ 
        progress.startAnimation(exitAnim); 
        progress.setVisibility(View.GONE); 
       } 
       imageView.startAnimation(enterAnim); 
       imageView.setVisibility(View.VISIBLE); 
      }else{ 
       if(null != progress){ 
        progress.startAnimation(enterAnim); 
//     progress.setVisibility(View.VISIBLE); 
        imageView.setVisibility(View.GONE); 
       }else{ 
        imageView.setImageResource(stub_id); 
        imageView.startAnimation(enterAnim); 
//     imageView.setVisibility(View.VISIBLE); 
       } 
      } 
     } 
    } 

    public void clearCache() { 
     //clear memory cache 
     cache.clear(); 

     //clear SD cache 
     File[] files=cacheDir.listFiles(); 
     for(File f:files) 
      f.delete(); 
    } 

} 
+0

나는 내 문제를 해결 ... 나는 권한을 추가하지 않았다. 그게 문제 였음을 나타냅니다. –

+0

@RobGThai Dude 님, 당신은 XML 레이아웃 중 하나에 진도 표시 줄을 부과하셨습니까? 게으른 어댑터 메이트 소스 코드는 어디서나, 전체 프로젝트에 게시합니까? –

+0

@ B.rohitNare 직접하지 마세요. 유니버설 이미지 로더 (Universal Image Loader) 또는 피카소 (Picasso)와 같은 타사 라이브러리를 사용하고 많은 시간과 두통을 덜어줍니다. – RobGThai

관련 문제