2012-02-01 8 views
0

私は遅延ロードクラスのImageloaderを使用してWebサーバーからイメージを取得しています。何らかの理由で同じアクティビティで約3リストビューlistviewsは間違った方法で画像をバインドします.iアクティビティをロードしてから、各リストビューの画像のロードを開始します。このための効率的な方法はありますか?前に作業していたLazyload ...どのように各画像をロードする必要がありますそれぞれのビューをポイントすることができますか?任意の助けをいただければ幸いです:) Lazyload loadは画像を同じアクティビティの複数のリストビューで間違ったビューにバインドします

public class ImageLoader { 
    private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>(); 
    private RotateAnimation rotate=null; 
    private String MainDirectory=".Beirut.com"; 
    private String Directory=".images"; 
    private File cacheDir; 

    public ImageLoader(Context context){ 
     //Make the background thread low priority. This way it will not affect the UI performance 
     photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); 

     //checking if the main Directory exist? 
     if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) 
      cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),MainDirectory); 
     else 
      cacheDir=context.getCacheDir(); 
     if(!cacheDir.exists()) 
      cacheDir.mkdirs(); 

     //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(),MainDirectory+"/"+Directory); 
     else 
      cacheDir=context.getCacheDir(); 
     if(!cacheDir.exists()) 
      cacheDir.mkdirs(); 
    } 

    final int stub_id=R.drawable.refresh_resized_silver; 
    public void DisplayImage(String url, Activity activity, ImageView imageView) 
    { 
     //Log.e("Image to load",url); 
     rotate=new RotateAnimation(0f, 360f, 
       Animation.RELATIVE_TO_SELF,0.5f, 
       Animation.RELATIVE_TO_SELF,0.5f); 
     rotate.setDuration(1000L); 
     rotate.setRepeatMode(Animation.INFINITE); 
     rotate.setRepeatCount(Animation.INFINITE); 
     imageView.setImageResource(stub_id); 
     imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 
     //imageView.setBackgroundResource(stub_id); 
     imageView.startAnimation(rotate); 
     if(cache.containsKey(url)){ 
      imageView.setImageBitmap(cache.get(url)); 
      imageView.invalidate(); 
      imageView.setScaleType(ScaleType.CENTER_INSIDE); 
      imageView.clearAnimation(); 
      //Log.e("Animation","Cleared"); 

     } 
     else 
     { 
      queuePhoto(url, activity, imageView); 
     }  
    } 

    private void queuePhoto(String url, Activity activity, ImageView imageView) 
    { 
     //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=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(); 
    } 
    public static Bitmap loadImageFromUrl(String url) {  
     InputStream inputStream; 
     Bitmap b;  
     try {   
      if(url.contains(" ")){     
       url=url.replace(" ", "%20");     
      } 
      //Log.e("Error link",url); 
      inputStream = (InputStream) new URL(url).getContent();    
      BitmapFactory.Options bpo= new BitmapFactory.Options();    
      bpo.inJustDecodeBounds = true;    
      bpo.inJustDecodeBounds = false;    
      if(bpo.outWidth>400){    
       bpo.inSampleSize = 1;    
       b=BitmapFactory.decodeStream(inputStream, null,bpo);  
      }else{ 
       bpo.inSampleSize=1; 
       b=BitmapFactory.decodeStream(inputStream, null,bpo); 
      } 
      return b;  
     }catch (IOException e) { 
      throw new RuntimeException(e);   
     } 
    } 

    private Bitmap getBitmap(String url) 
    { 
     //I 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 SD cache 
     Bitmap b = decodeFile(f); 
     if(b!=null){ 
      return b; 
     } 

     //from web 
     try { 
      Bitmap bitmap=null; 
      InputStream is=new URL(url).openStream(); 
      OutputStream os = new FileOutputStream(f); 
      Utils.CopyStream(is, os); 
      os.close(); 
      bitmap = decodeFile(f); 
      //bitmap=loadImageFromUrl(url); 
      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=300; 
      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; 

      try{ 
       return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);  
      }catch(FileNotFoundException e){ 
       return null; 
      } 
     } catch (FileNotFoundException e) {} 
     return null; 
    } 

    //Task for the queue 
    private class PhotoToLoad 
    { 
     public String url; 
     public ImageView imageView; 
     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; 
       } 
      } 
     } 
    } 

    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); 
          Activity a=(Activity)photoToLoad.imageView.getContext(); 
          a.runOnUiThread(bd); 
         } 
        } 
        if(Thread.interrupted()) 
         break; 
       } 
      } catch (InterruptedException e) { 
      } 
     } 
    } 

    PhotosLoader photoLoaderThread=new PhotosLoader(); 

    class BitmapDisplayer implements Runnable 
    { 
     Bitmap bitmap; 
     ImageView imageView; 
     public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;} 
     public void run() 
     { 
      if(bitmap!=null) 
       imageView.setImageBitmap(bitmap); 
      else 
       imageView.setImageResource(stub_id); 
      BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); 
      drawable.setAntiAlias(true); 
      imageView.setScaleType(ScaleType.CENTER_INSIDE); 
      imageView.clearAnimation(); 
      //Log.e("Animation","Cleared"); 
     } 
    } 

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

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

} 

とGetViewメソッドを次のように

public View getView(int position, View convertView, ViewGroup parent) { 
     View vi=convertView; 
     ViewHolder holder; 
     if(convertView==null){ 
      vi = inflater.inflate(R.layout.videoitem, null); 
      holder=new ViewHolder(); 
      holder.text=(TextView)vi.findViewById(R.id.text); 
      holder.image=(ImageView)vi.findViewById(R.id.image); 
      holder.typetext=(TextView)vi.findViewById(R.id.typetext); 
      holder.description=(TextView)vi.findViewById(R.id.description); 
      vi.setTag(holder); 
     }else{ 
      holder=(ViewHolder)vi.getTag(); 
     } 
     String dprow=""; 


     //data comes from search list 
     if(!data.get(position).getTitle().trim().equalsIgnoreCase("")){ 
      dprow+="<b><strike>"+data.get(position).getTitle().trim()+"</strike></b>"+"<br>"; 
     } 

     String urltoload="http://img.youtube.com/vi/"+data.get(position).getYoutube()+"/0.jpg"; 
     if(urltoload.contains(" ")){     
      urltoload=urltoload.replace(" ", "%20");     
     } 
     holder.text.setText(Html.fromHtml(dprow)); 
     holder.image.setTag(urltoload); 
     holder.typetext.setText(data.get(position).getType()); 
     holder.description.setText(urltoload); 

     imageLoader.DisplayImage(urltoload, activity, holder.image); 
     return vi; 
    } 

私は、ビューをリフレッシュしnotifyDataSetChangedを()を使用しますが、そのそれはとても遅い作ります。それ自身で各ビューの背景にイメージを読み込むための良い方法がありますか?

答えて

0

3つの異なるimage_loader(レイジーローダのオブジェクト)を使用して、各クラスの画像を読み込みます。遅延リストは古いリクエストとビューが存在する場合にチェックし、それをキャンセルして新しいイメージのリクエストを追加するためです。

+0

各リストビューには独自のカスタムアダプタがあり、このアダプタのコンストラクタでimage_loaderクラスが開始されていますが、まだ同じ問題が発生しています... –

+0

その後、問題をより明確にするためにコードを共有してください。 – Arslan

+0

コードを使用して質問を更新しました:) –

関連する問題