2013-08-16 64 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

謝謝董。這兩個建議幫助和它的工作:)它需要不到一分鐘下載。 。 。 –

相關問題