2013-08-16 38 views
1

我正在开发一个Android应用程序来从我的Web服务器下载图像。所有的代码运行良好。我正在使用Asynctask将图像下载到我的SD卡上。使用AsyncTask实现并发?

我在4mbps连接,但我的应用程序需要约8分钟下载3图像(2.5 MB)。我已经读过Asynctask自动管理线程创建的地方,那么现在我可以做些什么来实现并发?

我在下面发布我的代码。代码下面是我的Asynctask活动,下载图像从服务器到SD卡。

public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
private String url; 
Bitmap bitmap1; 
String sdCard; 
private final WeakReference<ImageView> imageViewReference; 

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

@Override 
// Actual download method, run in the task thread 
protected Bitmap doInBackground(String... params) { 

    // params comes from the execute() call: params[0] is the url. 
    bitmap1 = downloadBitmap(params[0]); 

    boolean avail = isMemorySizeAvailableAndroid(bitmap1.getRowBytes(), 
      Environment.isExternalStorageEmulated()); 
    if (avail) { 
     try { 
      sdCard = Environment.getExternalStorageDirectory().toString() 
        + "/MyCatalogue"; 
      File f1 = new File(sdCard); 
      if (!f1.exists()) { 
       f1.mkdirs(); 
      } 
      String filename1 = params[0].substring(params[0] 
        .lastIndexOf("/") + 1); 
      File file1 = new File(f1.toString(), filename1); 

      OutputStream stream1 = new FileOutputStream(file1); 
      bitmap1.compress(CompressFormat.JPEG, 100, stream1); 
      Log.w("Abhishek", "card is " + sdCard); 
     } catch (Exception e) { 
      e.printStackTrace(); 

     } 
    } 
    Log.w("ImageDownloader", "Success bitmap is" + bitmap1); 
    return downloadBitmap(params[0]); 
} 

protected static boolean isMemorySizeAvailableAndroid(long download_bytes, 
     boolean isExternalMemory) { 
    boolean isMemoryAvailable = false; 
    long freeSpace = 0; 

    // if isExternalMemory get true to calculate external SD card available 
    // size 
    if (isExternalMemory) { 
     try { 
      StatFs stat = new StatFs(Environment 
        .getExternalStorageDirectory().getPath()); 
      freeSpace = (long) stat.getAvailableBlocks() 
        * (long) stat.getBlockSize(); 
      if (freeSpace > download_bytes) { 
       isMemoryAvailable = true; 
      } else { 
       isMemoryAvailable = false; 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      isMemoryAvailable = false; 
     } 
    } else { 
     // find phone available size 
     try { 
      StatFs stat = new StatFs(Environment.getDataDirectory() 
        .getPath()); 
      freeSpace = (long) stat.getAvailableBlocks() 
        * (long) stat.getBlockSize(); 
      if (freeSpace > download_bytes) { 
       isMemoryAvailable = true; 
      } else { 
       isMemoryAvailable = false; 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      isMemoryAvailable = false; 
     } 
    } 

    return isMemoryAvailable; 
} 

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

    if (imageViewReference != null) { 
     ImageView imageView = imageViewReference.get(); 
     if (imageView != null) { 
      imageView.setImageBitmap(bitmap); 
     } 
    } 
} 

static Bitmap downloadBitmap(String url) { 
    final AndroidHttpClient client = 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; 
     } else { 
      Log.w("ImageDownloader", "Success " + statusCode 
        + " while retrieving bitmap from " + url); 
     } 

     final HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      InputStream inputStream = null; 
      try { 
       inputStream = entity.getContent(); 
       final Bitmap bitmap = BitmapFactory 
         .decodeStream(inputStream); 
       return bitmap; 
      } finally { 
       if (inputStream != null) { 
        inputStream.close(); 
       } 
       entity.consumeContent(); 
      } 
     } 
    } catch (Exception e) { 
     // Could provide a more explicit error message for IOException or 
     // IllegalStateException 
     getRequest.abort(); 
     Log.w("ImageDownloader", "Error while retrieving bitmap from " 
       + url); 
    } finally { 
     if (client != null) { 
      client.close(); 
     } 
    } 
    return null; 
} 
} 

回答

0

使用executeOnExecutor

http://developer.android.com/reference/java/util/concurrent/Executor.html

new BitmapDownloaderTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "your urls"); 

从文档

http://developer.android.com/reference/android/os/AsyncTask.html

当首次引入AsyncTasks被在单个后台线程串行执行报价。从DONUT开始,将其更改为允许多个任务并行操作的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。

1

为什么要在doInBackground()的开头和结尾两次下载图片两次?您可以直接返回刚刚下载的位图。

如果您的min sdk级别> = 11,则可以使用参数“THREAD_POOL_EXECUTOR”为并发调用AsyncTask的executeOnExecutor。

如果您的min sdk级别为< 11,则可以通过引用AsyncTask的源代码实现AsyncTask新API。

+0

谢谢董。这两个建议帮助和它的工作:)它需要不到一分钟下载。 。 。 –

相关问题