2010-11-28 44 views
0

該應用程序的功能非常簡單。它加載兩個RSS源,並在每個RSS源上包含兩個帶有標題,圖像和鏈接的項目。然後它下載圖像,將其保存到本地文件夾並顯示它們。所以兩個RSS源和4個圖像下載。使用AsyncTask加載圖像時的行爲不一致

我使用AsyncTask來做到這一點。因此,調用兩個AsyncTasks對象來加載兩個RSS提要和四個AsyncTasks來加載4個圖像。嘗試下載圖像時發生問題。對於第一次運行,它工作正常。但如果我繼續重新加載它們,有時AsyncTask不會執行任何操作。有時它不能讀取輸入流......非常奇怪。

是否有任何規則,我失蹤使用AsyncTask?

下面是我的代碼片段。

public class TunesAppsWidgetProvider extends AppWidgetProvider { 

private Intent taService = null; 
private static boolean widgetEnabled = false; 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    taService = new Intent(context, UpdateService.class); 
    context.startService(taService); 
} 

public static class UpdateService extends Service { 


    @Override 
    public void onStart(Intent intent, int startId) { 
     Log.d(Constants.TAG, "Service: onStart()"); 
     Context context = getApplicationContext(); 
     mViews = new RemoteViews(context.getPackageName(), R.layout.tunesappswidget); 

     thisWidget = new ComponentName(this, TunesAppsWidgetProvider.class); 
     manager = AppWidgetManager.getInstance(this); 

     buildFeedUpdate(); 

     this.stopSelf(); 
     Log.d(Constants.TAG, "Stop Service"); 
    } 

    public void buildFeedUpdate() { 
     Log.d(Constants.TAG, "buildFeedUpdate"); 
     Context context = getApplicationContext(); 

     feedParser_0 = new FeedParser(context, Constants.FEED_ID_0); 
     feedParser_1 = new FeedParser(context, Constants.FEED_ID_1); 

     feedTask_0 = new LoadFeedTask(); 
     feedTask_0.execute(
       new LoadFeedTask.Payload(
         feedParser_0, 
         UpdateService.this 
       ) 
     ); 

     feedTask_1 = new LoadFeedTask(); 
     feedTask_1.execute(
       new LoadFeedTask.Payload(
         feedParser_1, 
         UpdateService.this 
       ) 
     ); 
    } 

    public void buildCoverUpdate(byte feedID, List<Message> feedRSS, String operator) { 
     Context context = getApplicationContext(); 

     Log.d(Constants.TAG, "buildCoverUpdate: " + feedID); 
     try { 
      switch(feedID) { 
       case Constants.FEED_ID_0: 
         coverImage_0 = new CoverImage(context, feedRSS.get(Constants.ITEM_IDX_0).getImageLink(), Constants.SLOT_0); 

      coverImageTask_0 = new LoadCoverImageTask(); 
         coverImageTask_0.execute(
          new LoadCoverImageTask.Payload(
            coverImage_0, 
            UpdateService.this 
          ) 
         ); 

         coverImage_1 = new CoverImage(context, feedRSS.get(Constants.ITEM_IDX_1).getImageLink(), Constants.SLOT_1); 

         coverImageTask_1 = new LoadCoverImageTask(); 
          coverImageTask_1.execute(
           new LoadCoverImageTask.Payload(
            coverImage_1, 
            UpdateService.this 
           ) 
         ); 
        break; 

       case Constants.FEED_ID_1: 
         coverImage_2 = new CoverImage(context, feedRSS.get(Constants.ITEM_IDX_0).getImageLink(), Constants.SLOT_2, operator); 
        coverImageTask_2 = new LoadCoverImageTask(); 
         coverImageTask_2.execute(
           new LoadCoverImageTask.Payload(
             coverImage_2, 
             UpdateService.this 
           ) 
         ); 

         coverImage_3 = new CoverImage(context, feedRSS.get(Constants.ITEM_IDX_1).getImageLink(), Constants.SLOT_3, operator); 
         bm_3 = coverImage_3.getDefaultCoverImage(); 
          coverImageTask_3 = new LoadCoverImageTask(); 
          coverImageTask_3.execute(
           new LoadCoverImageTask.Payload(
            coverImage_3, 
            UpdateService.this 
           ) 
         ); 
        break; 

       default: 
        break; 
      } 
     } 
     catch(Exception e) { 
      Log.d(Constants.TAG, "buildCoverUpdate: " + e.toString()); 
     } 
    } 

}

及以下代碼是用於加載圖像。有時候,即使調用「execute」,doInBackground也不會被調用。有時它卡在'Bitmap bitmap = BitmapFactory.decodeStream(in)'這裏,並且永遠不會退出。

protected LoadCoverImageTask.Payload doInBackground(LoadCoverImageTask.Payload... param) { 
    HttpURLConnection httpConn = null; 
    InputStream in; 
    File imageFile; 
    FileOutputStream fos; 
    int slotIdx = param[0].coverImage.getSlotIndex(); 
    System.setProperty("http.keepAlive", "false"); 

    try{ 
     URL fileURL = new URL(param[0].coverImage.getFileURL()); 
     httpConn = (HttpURLConnection) fileURL.openConnection(); 
     Log.d(Constants.TAG , "openConn: Slot " + slotIdx); 

     httpConn.setConnectTimeout(10000); 

     if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) { 
      Log.d(Constants.TAG , "200OK: Slot " + slotIdx + ": " + fileURL.toString()); 

      in = httpConn.getInputStream(); 
      imageFile = new File(param[0].coverImage.getFullFilePath()); 
      fos = new FileOutputStream(imageFile); 

      try { 
       Bitmap bitmap = BitmapFactory.decodeStream(in); 
       Log.d(Constants.TAG , "200OK: Slot " + slotIdx + " decodeStream(in);"); 
       if(bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos) == true) { 
        fos.flush(); 
        fos.close(); 
        in.close(); 
        Log.d(Constants.TAG , "200OK-decodeOK: Slot " + slotIdx); 
        param[0].result = Constants.TRUE; 
       } 
       else { 
        fos.flush(); 
        fos.close(); 
        in.close(); 
        Log.d(Constants.TAG , "200OK-decodeFail: Slot " + slotIdx); 
        param[0].result = Constants.FALSE; 
       } 
      } 
      catch(NullPointerException e) { 
       Log.d(Constants.TAG , "Slot " + slotIdx + ":" + e.toString()); 
       param[0].result = Constants.RETRY; 
      } 
     } 
     else { 
      Log.d(Constants.TAG , "Slot " + slotIdx + ":" + httpConn.getResponseCode()); 
      param[0].result = Constants.FALSE; 
     } 

    } catch(SocketTimeoutException e) { 
     Log.d(Constants.TAG , "Time Out: " + slotIdx + ":" + e.toString()); 
    } catch(Exception e) { 
     Log.d(Constants.TAG , "Slot " + slotIdx + ":" + e.toString()); 
     param[0].result = Constants.FALSE; 
    } 
    finally { 
     if(httpConn != null) httpConn.disconnect(); 
     Log.d(Constants.TAG , "Slot " + slotIdx + ":httpConn.disconnect"); 
    } 
    return param[0]; 
} 

我堅持在這幾天的..請幫助...

回答

1

也許問題是不是在你的代碼。 BitmapFactory.decodeStream中存在一個錯誤,如果您使用http連接的InputStream,它有時不會很好地加載圖像。

http://code.google.com/p/android/issues/detail?id=6066瞭解更多信息

簡單的解決方案,對我來說是下載全部內容數據到緩衝區,然後 使用BitmapFactory.decodeByteArray方法的工作原理:

InputStream is = httpCon.getInputStream(); 
byte [] content = inputStreamToByteArray2(is); 
image = BitmapFactory.decodeByteArray(content, 0, content.length); 


public static final byte[] inputStreamToByteArray(InputStream is) throws IOException { 
    BufferedInputStream bis = new BufferedInputStream(is); 
    ByteArrayOutputStream buf = new ByteArrayOutputStream(); 
    int result = bis.read(); 
    while(result !=-1) { 
     byte b = (byte)result; 
     buf.write(b); 
     result = bis.read(); 
    } 
    return buf.toByteArray(); 
} 

,或者如果你不這樣做想讀1字節:

public static final byte[] inputStreamToByteArray(InputStream is) throws IOException { 
    BufferedInputStream bis = new BufferedInputStream(is); 
    ByteArrayOutputStream buf = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[256]; 
    int result = bis.read(buffer); 
    while(result > 0) { 
     buf.write(buffer, 0, result); 
     result = bis.read(buffer); 
    } 
    return buf.toByteArray(); 
} 
+0

謝謝你的幫助。那麼,如果來自http連接的inputstream運行不正常,我應該使用什麼來加載圖像? – juniano 2010-12-14 05:42:50