0

我相對較新的android開發,我想創建一個自定義ListView與ImageView和TextView。我將URL轉換爲位圖圖像,然後嘗試在imageView中顯示圖像。但是,我收到一個錯誤,我的應用程序立即崩潰。能夠在我的imageView中顯示drawable,我做了一些修改,並試圖顯示一個位圖,然後我的應用程序崩潰。任何幫助將不勝感激。這裏是我的3類:CustomListView與位圖 - OutOfMemory錯誤

編輯我用一個asynctask獲得位圖圖像在一個單獨的線程,現在我的應用程序不會崩潰了。但是當我開始活動時它不顯示列表視圖。這是我更新的代碼。

編輯我改變了我的代碼,我只是在我的異步任務的執行方法中傳遞一個imageView。我現在能夠看到我的列表視圖中的文字,但我沒有看到圖像。這是我編輯的代碼。

編輯我用調試器找出爲什麼位圖沒有顯示,我發現我的位圖變量爲空。這是因爲我沒有添加Internet權限。添加權限後我的應用程序開始在給定的行崩潰:

b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream()); 

我已經得到一個RuntimeException由於OutOfMemory錯誤。我不知道如何解決這個問題。我將不勝感激任何幫助。謝謝 !

這裏是我的LoadImage的AsyncTask類:

public class LoadImage extends AsyncTask<String, Integer, Bitmap>{ 

    Context callingContext = null; 
    Bitmap b = null; 

    ImageView view; 

    public LoadImage(ImageView view){ 

     this.view = view; 
    } 

    @Override 
    protected Bitmap doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     String p_url = "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png"; 

     Bitmap b = null; 
     try { 
      URL image_url = new URL(p_url); 
      b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream()); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return b; 
    } 



    @Override 
    protected void onPostExecute(Bitmap result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     view.setImageBitmap(result); 

    } 
} 
+0

你可以請你發佈錯誤和回溯(如果適用)。你可以在logcat中找到回溯。 – MJD 2012-07-23 16:15:56

+1

您下載的圖像有多大?在Android上,你有一個(非常)有限的內存預算。根據設備,數量會發生變化,但最小值爲16M(http://stackoverflow.com/questions/1702323/android-available-ram)。如果圖像真的很大,你可以試着看看:http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap -object/823966#823966。 – MJD 2012-07-24 13:59:02

回答

2

您的代碼崩潰,因爲你正在加載的圖像文件,關閉服務器的UI線程上,而在嚴格的模式。這通常被認爲是不好的做法,因爲如果圖片需要很長時間才能下載,您的應用程序將顯示鎖定。

嚴格模式強制崩潰(其拋出異常)。如果你禁用嚴格模式,它應該讓你的應用程序正常工作。但是,在UI線程上執行網絡I/O的問題仍然存在。

更好的長期解決方案是使用類似於AsyncTask的東西。這會在不同的線程上加載你的圖像,從而保持你的應用程序響應。 AsyncTask的文檔有一個下載圖像的簡單示例,this helper page有更多信息。

舉一個例子,我可能會更改您的代碼是這樣的(請注意我在寫這沒有一個試運行,所以有可能是一些錯誤):

我會改變你的列表條目爲:

public class CustomList { 

    public String iconUrl; 
    public String title; 
    public CustomList(){ 
     super(); 
    } 

    public CustomList(String icon, String title) { 
     super(); 
     this.icon = icon; 
     this.title = title; 
    } 
} 

然後只傳遞圖標URL到您的列表。

下創建的AsyncTask:不是設置圖像

public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> { 
    public ImageDownloader(ImageView view){ 
      mView = view; 
    } 

    protected Bitmap doInBackground(String... url) { 
     Bitmap b = null; 
     try { 
      URL image_url = new URL(url); 
      b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream()); 
      list_data = new CustomList[]{ 
        new CustomList(b,"Android")}; 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return b; 
    } 

    protected void onPostExecute(Bitmap result) { 
     mView.setImageBitmap(result); 
    } 
    ImageView mView; 
} 

然後爲適配器,這樣做:

new ImageDownloader(holder.thumbnail).execute(cl.icon); 

這應該足以讓你開始。請注意,此示例有幾個問題:

  1. 存在潛在的內存泄漏。一般而言,您應該像在我一樣,在AsyncTask中不參照Views或Activities(或其他這樣的對象)。
  2. 如果您旋轉手機並且 列表發生變化,您可能會顯示舊的縮略圖。
  3. 如果 視圖被回收,則可能會顯示舊的縮略圖。
+0

謝謝你的幫助!我試圖尋找助手頁面,我無法理解如何使用異步任務以及自定義陣列適配器來加載位圖圖像。我嘗試使用可運行的線程,並且我的應用程序又崩潰了。我將編輯我的代碼。如果你能告訴我我哪裏出錯了,我將不勝感激。 – AndroidDev93 2012-07-23 16:55:48

+0

謝謝你的例子!但是,我已經試圖讓我的程序在異步任務中工作。我已更新我的代碼,並添加了異步任務類。我目前的問題是,我的listview沒有得到顯示。 – AndroidDev93 2012-07-23 19:11:11

+0

我已經更改了我的代碼。我現在按照你的建議去做。不過,我仍然無法在列表視圖中看到圖片,儘管我現在看到了文字。 – AndroidDev93 2012-07-24 03:16:03