2014-01-15 45 views
1

我有一个带有img标签的html-content字符串。对于具有图像的URL我使用:使用android-query从服务器html sourse加载图像

Spanned htmlSpan = Html.fromHtml(item.message, imgGetter, null); 
descriptionView.setText(htmlSpan); 

Html.ImageGetter必须实现方法getDrawable应返回可绘制对象

Html.ImageGetter imgGetter = new Html.ImageGetter() { 
    public Drawable getDrawable(String source) { 
     aq.ajax(Cfg.SITE_URL+source, Drawable.class, new AjaxCallback<Drawable>(){ 
      @Override 
      public void callback(String url, Drawable d, AjaxStatus status) { 
       //Something here 
      } 
     }); 

     return result; // nothing for result now 
    } 
}; 

我需要帮助。如何组织这个?

UPD:AQ是aq = new AQuery(this);https://code.google.com/p/android-query/wiki/AsyncAPI

回答

0

所有图像下载

+1

它似乎是一个模拟的android查询。它允许在TextView中显示图像吗? –

+0

你可以重写metod当图像加载器pu图像scr的imageview为textgro backgroind –

0

使用通用映像加载您需要Android查询?我认为这不是最好的方法。 其实有一堆正是这种做库,像

https://github.com/nostra13/Android-Universal-Image-Loaderhttp://square.github.io/picasso/

而且,如果你想有一个简单的代码,你可以用这个例子形成android developers blog

至极主要代码是这样的

/* 
* Copyright (C) 2010 The Android Open Source Project 
* 
* 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.example.android.imagedownloader; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.HttpStatus; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Color; 
import android.graphics.drawable.ColorDrawable; 
import android.graphics.drawable.Drawable; 
import android.net.http.AndroidHttpClient; 
import android.os.AsyncTask; 
import android.os.Handler; 
import android.util.Log; 
import android.widget.ImageView; 

import java.io.FilterInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.ref.SoftReference; 
import java.lang.ref.WeakReference; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.concurrent.ConcurrentHashMap; 

/** 
* This helper class download images from the Internet and binds those with the provided ImageView. 
* 
* <p>It requires the INTERNET permission, which should be added to your application's manifest 
* file.</p> 
* 
* A local cache of downloaded images is maintained internally to improve performance. 
*/ 
public class ImageDownloader { 
    private static final String LOG_TAG = "ImageDownloader"; 

    public enum Mode { NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT } 
    private Mode mode = Mode.NO_ASYNC_TASK; 

    /** 
    * Download the specified image from the Internet and binds it to the provided ImageView. The 
    * binding is immediate if the image is found in the cache and will be done asynchronously 
    * otherwise. A null bitmap will be associated to the ImageView if an error occurs. 
    * 
    * @param url The URL of the image to download. 
    * @param imageView The ImageView to bind the downloaded image to. 
    */ 
    public void download(String url, ImageView imageView) { 
     resetPurgeTimer(); 
     Bitmap bitmap = getBitmapFromCache(url); 

     if (bitmap == null) { 
      forceDownload(url, imageView); 
     } else { 
      cancelPotentialDownload(url, imageView); 
      imageView.setImageBitmap(bitmap); 
     } 
    } 

    /* 
    * Same as download but the image is always downloaded and the cache is not used. 
    * Kept private at the moment as its interest is not clear. 
     private void forceDownload(String url, ImageView view) { 
      forceDownload(url, view, null); 
     } 
    */ 

    /** 
    * Same as download but the image is always downloaded and the cache is not used. 
    * Kept private at the moment as its interest is not clear. 
    */ 
    private void forceDownload(String url, ImageView imageView) { 
     // State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys. 
     if (url == null) { 
      imageView.setImageDrawable(null); 
      return; 
     } 

     if (cancelPotentialDownload(url, imageView)) { 
      switch (mode) { 
       case NO_ASYNC_TASK: 
        Bitmap bitmap = downloadBitmap(url); 
        addBitmapToCache(url, bitmap); 
        imageView.setImageBitmap(bitmap); 
        break; 

       case NO_DOWNLOADED_DRAWABLE: 
        imageView.setMinimumHeight(156); 
        BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); 
        task.execute(url); 
        break; 

       case CORRECT: 
        task = new BitmapDownloaderTask(imageView); 
        DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task); 
        imageView.setImageDrawable(downloadedDrawable); 
        imageView.setMinimumHeight(156); 
        task.execute(url); 
        break; 
      } 
     } 
    } 

    /** 
    * Returns true if the current download has been canceled or if there was no download in 
    * progress on this image view. 
    * Returns false if the download in progress deals with the same url. The download is not 
    * stopped in that case. 
    */ 
    private static boolean cancelPotentialDownload(String url, ImageView imageView) { 
     BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); 

     if (bitmapDownloaderTask != null) { 
      String bitmapUrl = bitmapDownloaderTask.url; 
      if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) { 
       bitmapDownloaderTask.cancel(true); 
      } else { 
       // The same URL is already being downloaded. 
       return false; 
      } 
     } 
     return true; 
    } 

    /** 
    * @param imageView Any imageView 
    * @return Retrieve the currently active download task (if any) associated with this imageView. 
    * null if there is no such task. 
    */ 
    private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) { 
     if (imageView != null) { 
      Drawable drawable = imageView.getDrawable(); 
      if (drawable instanceof DownloadedDrawable) { 
       DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable; 
       return downloadedDrawable.getBitmapDownloaderTask(); 
      } 
     } 
     return null; 
    } 

    Bitmap downloadBitmap(String url) { 
     final int IO_BUFFER_SIZE = 4 * 1024; 

     // AndroidHttpClient is not allowed to be used from the main thread 
     final HttpClient client = (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() : 
      AndroidHttpClient.newInstance("Android"); 
     final HttpGet getRequest = new HttpGet(url); 

     try { 
      HttpResponse response = client.execute(getRequest); 
      final int statusCode = response.getStatusLine().getStatusCode(); 
      if (statusCode != HttpStatus.SC_OK) { 
       Log.w("ImageDownloader", "Error " + statusCode + 
         " while retrieving bitmap from " + url); 
       return null; 
      } 

      final HttpEntity entity = response.getEntity(); 
      if (entity != null) { 
       InputStream inputStream = null; 
       try { 
        inputStream = entity.getContent(); 
        // return BitmapFactory.decodeStream(inputStream); 
        // Bug on slow connections, fixed in future release. 
        return BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); 
       } finally { 
        if (inputStream != null) { 
         inputStream.close(); 
        } 
        entity.consumeContent(); 
       } 
      } 
     } catch (IOException e) { 
      getRequest.abort(); 
      Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e); 
     } catch (IllegalStateException e) { 
      getRequest.abort(); 
      Log.w(LOG_TAG, "Incorrect URL: " + url); 
     } catch (Exception e) { 
      getRequest.abort(); 
      Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e); 
     } finally { 
      if ((client instanceof AndroidHttpClient)) { 
       ((AndroidHttpClient) client).close(); 
      } 
     } 
     return null; 
    } 

    /* 
    * An InputStream that skips the exact number of bytes provided, unless it reaches EOF. 
    */ 
    static class FlushedInputStream extends FilterInputStream { 
     public FlushedInputStream(InputStream inputStream) { 
      super(inputStream); 
     } 

     @Override 
     public long skip(long n) throws IOException { 
      long totalBytesSkipped = 0L; 
      while (totalBytesSkipped < n) { 
       long bytesSkipped = in.skip(n - totalBytesSkipped); 
       if (bytesSkipped == 0L) { 
        int b = read(); 
        if (b < 0) { 
         break; // we reached EOF 
        } else { 
         bytesSkipped = 1; // we read one byte 
        } 
       } 
       totalBytesSkipped += bytesSkipped; 
      } 
      return totalBytesSkipped; 
     } 
    } 

    /** 
    * The actual AsyncTask that will asynchronously download the image. 
    */ 
    class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
     private String url; 
     private final WeakReference<ImageView> imageViewReference; 

     public BitmapDownloaderTask(ImageView imageView) { 
      imageViewReference = new WeakReference<ImageView>(imageView); 
     } 

     /** 
     * Actual download method. 
     */ 
     @Override 
     protected Bitmap doInBackground(String... params) { 
      url = params[0]; 
      return downloadBitmap(url); 
     } 

     /** 
     * Once the image is downloaded, associates it to the imageView 
     */ 
     @Override 
     protected void onPostExecute(Bitmap bitmap) { 
      if (isCancelled()) { 
       bitmap = null; 
      } 

      addBitmapToCache(url, bitmap); 

      if (imageViewReference != null) { 
       ImageView imageView = imageViewReference.get(); 
       BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); 
       // Change bitmap only if this process is still associated with it 
       // Or if we don't use any bitmap to task association (NO_DOWNLOADED_DRAWABLE mode) 
       if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) { 
        imageView.setImageBitmap(bitmap); 
       } 
      } 
     } 
    } 


    /** 
    * A fake Drawable that will be attached to the imageView while the download is in progress. 
    * 
    * <p>Contains a reference to the actual download task, so that a download task can be stopped 
    * if a new binding is required, and makes sure that only the last started download process can 
    * bind its result, independently of the download finish order.</p> 
    */ 
    static class DownloadedDrawable extends ColorDrawable { 
     private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference; 

     public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) { 
      super(Color.BLACK); 
      bitmapDownloaderTaskReference = 
       new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask); 
     } 

     public BitmapDownloaderTask getBitmapDownloaderTask() { 
      return bitmapDownloaderTaskReference.get(); 
     } 
    } 

    public void setMode(Mode mode) { 
     this.mode = mode; 
     clearCache(); 
    } 


    /* 
    * Cache-related fields and methods. 
    * 
    * We use a hard and a soft cache. A soft reference cache is too aggressively cleared by the 
    * Garbage Collector. 
    */ 

    private static final int HARD_CACHE_CAPACITY = 10; 
    private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds 

    // Hard cache, with a fixed maximum capacity and a life duration 
    private final HashMap<String, Bitmap> sHardBitmapCache = 
     new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY/2, 0.75f, true) { 
     @Override 
     protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) { 
      if (size() > HARD_CACHE_CAPACITY) { 
       // Entries push-out of hard reference cache are transferred to soft reference cache 
       sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue())); 
       return true; 
      } else 
       return false; 
     } 
    }; 

    // Soft cache for bitmaps kicked out of hard cache 
    private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache = 
     new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY/2); 

    private final Handler purgeHandler = new Handler(); 

    private final Runnable purger = new Runnable() { 
     public void run() { 
      clearCache(); 
     } 
    }; 

    /** 
    * Adds this bitmap to the cache. 
    * @param bitmap The newly downloaded bitmap. 
    */ 
    private void addBitmapToCache(String url, Bitmap bitmap) { 
     if (bitmap != null) { 
      synchronized (sHardBitmapCache) { 
       sHardBitmapCache.put(url, bitmap); 
      } 
     } 
    } 

    /** 
    * @param url The URL of the image that will be retrieved from the cache. 
    * @return The cached bitmap or null if it was not found. 
    */ 
    private Bitmap getBitmapFromCache(String url) { 
     // First try the hard reference cache 
     synchronized (sHardBitmapCache) { 
      final Bitmap bitmap = sHardBitmapCache.get(url); 
      if (bitmap != null) { 
       // Bitmap found in hard cache 
       // Move element to first position, so that it is removed last 
       sHardBitmapCache.remove(url); 
       sHardBitmapCache.put(url, bitmap); 
       return bitmap; 
      } 
     } 

     // Then try the soft reference cache 
     SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url); 
     if (bitmapReference != null) { 
      final Bitmap bitmap = bitmapReference.get(); 
      if (bitmap != null) { 
       // Bitmap found in soft cache 
       return bitmap; 
      } else { 
       // Soft reference has been Garbage Collected 
       sSoftBitmapCache.remove(url); 
      } 
     } 

     return null; 
    } 

    /** 
    * Clears the image cache used internally to improve performance. Note that for memory 
    * efficiency reasons, the cache will automatically be cleared after a certain inactivity delay. 
    */ 
    public void clearCache() { 
     sHardBitmapCache.clear(); 
     sSoftBitmapCache.clear(); 
    } 

    /** 
    * Allow a new delay before the automatic cache clear is done. 
    */ 
    private void resetPurgeTimer() { 
     purgeHandler.removeCallbacks(purger); 
     purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE); 
    } 
} 
相关问题