2013-12-20 28 views
0

我很絕望,我不知道該怎麼辦。我已經嘗試了很多事情來解決這個問題,並且我總是離開OutOfMemory錯誤。我有一個通用圖像裝載機圖書館和許多其他互聯網修復嘗試,但我總是得到這個錯誤:GridView 400上的Android java.lang.OutOfMemoryError Drawables 25Kb大小

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715) 
at android.content.res.Resources.loadDrawable(Resources.java:1713) 
at android.content.res.Resources.getDrawable(Resources.java:585) 
at android.view.View.setBackgroundResource(View.java:7659) 
at com.crystalsoftdesign.hearthstone.AdapterImage.getView(AdapterImage.java:153) 
at android.widget.AbsListView.obtainView(AbsListView.java:1513) 
at android.widget.GridView.makeAndAddView(GridView.java:1226) 
at android.widget.GridView.makeRow(GridView.java:272) 
at android.widget.GridView.fillDown(GridView.java:225) 
at android.widget.GridView.fillGap(GridView.java:192) 
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3498) 
at android.widget.AbsListView.onTouchEvent(AbsListView.java:2327) 
at android.view.View.dispatchTouchEvent(View.java:3934) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:977) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1016) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1016) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1016) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1016) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1016) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691) 
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125) 
at android.app.Activity.dispatchTouchEvent(Activity.java:2096) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675) 
at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2215) 
at android.view.ViewRoot.handleMessage(ViewRoot.java:1899) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:123) 
at android.app.ActivityThread.main(ActivityThread.java:3701) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
at dalvik.system.NativeStart.main(Native Method) 

我的應用程序總共有393圖像在GridView。每個圖像都是一個每個25KB的JPG文件。我真的需要幫助,因爲現在我完全不知道該怎麼做。

我把我所有的適配器代碼放在這裏,看看是否有專業人士或瞭解很多可以幫助我。

public AdapterImage(Context c, ArrayList<BeanCarta> coleccion, int modificarCantidadColumnas, boolean pantallaEditColeccion, Map<Integer, Integer> mapIdsGrid, ArrayList<BeanCarta> mazoVisual){ 
     try { 
      this.mContext = c; 
      this.coleccion = coleccion; 
      this.modificarCantidadColumnas = modificarCantidadColumnas; 
      this.pantallaEditColeccion = pantallaEditColeccion; 
      this.mapIdsGrid = mapIdsGrid; 
      this.mazoVisual = mazoVisual; 
     } catch (Exception e) { 
      Utils.logErrorStart(log, "AdapterImage"); 
      Utils.logErrorIni(this.log, "constructor"); 
      Utils.appendLog(this.log, e, null); 
     } 
    } 

    public void setAdaptadorParametros(ArrayList<BeanCarta> coleccion, int modificarCantidadColumnas, boolean coleccionPersonal, Map<Integer, Integer> mapIdsGrid){ 
     this.coleccion = coleccion; 
     this.modificarCantidadColumnas = modificarCantidadColumnas; 
     this.pantallaEditColeccion = coleccionPersonal; 
     this.mapIdsGrid = mapIdsGrid; 
    } 

    @Override 
    public int getCount() { 
     return this.coleccion.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return this.coleccion.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    public static class ViewHolder{ 
     ImageView elemImg; 
     LinearLayout elemLayout; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 
     if (convertView == null) { 
      holder = new ViewHolder(); 
      LayoutInflater vi = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = vi.inflate(R.layout.element_grid, null); 

      holder.elemImg = (ImageView) convertView.findViewById(R.id.imagenGrid); 
      holder.elemLayout = (LinearLayout) convertView.findViewById(R.id.imagenGridLay); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

      this.carta = this.coleccion.get(position); 
      holder.elemImg.setScaleType(ImageView.ScaleType.CENTER_CROP); 

      //Detectar si el view del grid, que corresponde a una carta, ya tiene un id asignado. 
      //En tal caso se le asigna el mismo id. 
      this.id = 0; 
      if (this.mapIdsGrid.containsKey(this.carta.getId())){ 
       this.id = this.mapIdsGrid.get(this.carta.getId()); 
      }else{ 
       this.id = Utils.getRandomId(this.mContext); 
       this.mapIdsGrid.put(this.carta.getId(), this.id); 
      } 
      holder.elemImg.setId(this.id); 
      holder.elemLayout.setId(this.id); 

      //Detectar la trasparencia de la carta si hay cartas disponibles en la colección. 
      if (!this.pantallaEditColeccion && this.carta.getCantidad() <= 0){ 
       holder.elemImg.setVisibility(View.VISIBLE); 
      }else{ 
       holder.elemImg.setVisibility(View.GONE); 
      } 

      if (!this.pantallaEditColeccion){ 
       int cantidadMazo = this.mazoVisual.size(); 
       for (int i = 0; i < cantidadMazo; i++) { 
        if(carta.getId() == this.mazoVisual.get(i).getId()){ 
         if(this.mazoVisual.get(i).getCantidad() == Constantes.MAXIMO_COPIAS_MAZO || Constantes.RAREZA_LEGENDARIA.equals(this.mazoVisual.get(i).getRareza())){ 
          holder.elemImg.setVisibility(View.VISIBLE); 
          break; 
         } 
        } 
       } 
      } 


      if (this.metrics == null){ 
       this.metrics = parent.getResources().getDisplayMetrics(); 
       this.cartaWFinal = (this.metrics.widthPixels/this.modificarCantidadColumnas) - MARGEN_CARTA; 
       this.cartaHFinal = 392*this.cartaWFinal/278; 
       this.gridView = new GridView.LayoutParams(this.cartaWFinal, this.cartaHFinal); 
      } 
      holder.elemLayout.setLayoutParams(this.gridView); 
      holder.elemLayout.setBackgroundResource(Utils.getIntDrawableByName(this.coleccion.get(position).getImagen(), this.mContext)); 

     return convertView; 
    } 

    public DisplayMetrics getMetrics() { 
     return metrics; 
    } 

    public void setMetrics(DisplayMetrics metrics) { 
     this.metrics = metrics; 
    } 

我使用了不同的librearies和differents代碼來改善它,並且從未解決它。我試圖用Eclipe的記憶分析器進行分析,但我無法解決這個問題,因爲我不是專業人員,我不知道如何使用這些工具。

如果您使用解決方案代碼發佈示例,那麼您可以幫助我更多。或者向我提供一個帶有示例解釋的教程,因爲我是西班牙語,不是專業的開發人員,很多時候我很難理解人們解釋的一些事情。

在此先感謝。

+0

你在模擬器上運行你的應用程序嗎? –

+0

是的,我嘗試使用模擬器和我的設備。該應用位於Google Play上,並且有人向我報告此問題。此錯誤出現在仿真器和物理設備上。 – waldette

+0

在清單中添加大堆屬性true –

回答

0

holder.elemLayout.setBackgroundResource(Utils.getIntDrawableByName(this.coleccion.get(position).getImagen(),this.mContext)); - 這可能是內存不足錯誤的原因。 您需要將縮小(較小)版本的圖像加載到內存中,以將其附加到網格視圖中。遵循這些inJustDecodeBounds步驟 - 首先解碼= true來檢查圖像的尺寸

final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(<your image>, options);//use appropriate parameters for the method. 

計算inSampleSize

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);//reqWidth and reqHeight are width and height of your grid view cell. 

方法計算樣本量

public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

解碼與inSampleSize圖像設置

options.inJustDecodeBounds = false; 
    Bitmap scaledBitmap = BitmapFactory.decodeResource(<your image>, options); 

最後, 這集作爲scaledBitmap背景爲您holder.elemLayout。

this for more details

+0

我可以將此代碼放在getView()方法上還是我需要在構造函數上執行? – waldette

+0

BitmapDrawable drawable = new BitmapDrawable(bitmap); holder.elemLayout.setBackgroundDrawable(drawable); //這裏位圖是我們縮小的位圖。 – nikvs

+0

是的,我明白了,我認爲這是解決方案。但我的問題是,如果我可以把所有這些代碼放在我的getView()方法中,或者我需要將所有的代碼放在構造器或其他站點中? – waldette

相關問題