2016-05-21 2 views
0

Я по-прежнему новичок в разработке приложений для Android, и я хотел бы создать список, заполненный таможнями (каждый из них содержит изображение и текстовое изображение). Эта часть отлично работает BUT ...Исключение из памяти, вызванное списком растровых изображений

Я добавил кнопку, которая позволяет мне снимать фотографию с камеры по умолчанию и сохранять ее во внешней памяти. Когда я снимаю фотографию, я также создаю новый объект с именем фотографии и Uri.

Возможно, вы поняли, что я загружаю список объектов в ListView. Но только после 6 или 7 фотографий я получил это «Исключение из памяти».

Мой смартфон принимает фотографии с высоким разрешением, и я думаю, что фото полностью загружено в память, что вызывает это исключение. Я пробовал много вещей, как этот урок от разработчика android: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html. Но это ничего не меняет. Я, очевидно, что-то делаю неправильно.

Так я был бы очень признателен, если кто-то может помочь мне: D

PS: Мой ListView находится в фрагменте, я не знаю, если это важно. Кроме того, когда я снимаю фотографию с задней камеры, фотография не отображается в списке:/просто появляется пустое. Но когда я беру его с передней камерой, это отображается правильно.

Мой код: MainFragment.java

public class MainFragment extends Fragment{ 

private ListView frais_listView; 
private Uri saved_image_uri; 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View rootView=inflater.inflate(R.layout.fragment_main,container,false); 
    return rootView; 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.new_frais_button); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Intent newfraisactivity = new Intent(getActivity(),NewFraisActivity.class); 
      startActivity(newfraisactivity); 
     } 
    }); 

    FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.new_frais_photo_button); 
    fab2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 

      //Get the current date 
      Calendar calendar=Calendar.getInstance(); 
      SimpleDateFormat date_format=new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss"); 
      String formatted_date=date_format.format(calendar.getTime()); 

      //Open the default camera and save the photo 
      Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      saved_image_uri=Uri.fromFile(new File(Utilities.getImages_folder()+"/Frais"+formatted_date+".png")); 
      camera.putExtra(MediaStore.EXTRA_OUTPUT,saved_image_uri); 
      startActivityForResult(camera,0); 
     } 
    }); 

    //Load the list of frais in the listview using a custom adapter FraisAdapter 
    frais_listView=(ListView)getActivity().findViewById(R.id.frais_listview); 
    FraisAdapter my_adapter=new FraisAdapter(getActivity().getBaseContext(),R.layout.frais_item_for_listview,Frais.frais_list); 
    frais_listView.setAdapter(my_adapter); 
} 

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // TODO Auto-generated method stub 
    super.onActivityResult(requestCode, resultCode, data); 

    //If the photo has been taken, create a new Frais object and add it to the list 
    if(resultCode != 0) 
    { 
     String filename=(new File(saved_image_uri.toString())).getName(); 
     int position = filename.lastIndexOf("."); 
     String filename_noext = position > 0 ? filename.substring(0, position) : filename; 
     Frais.frais_list.add(new Frais(filename_noext,null,saved_image_uri)); 
    } 
} 

}

FraisAdapter.java

public class FraisAdapter extends ArrayAdapter<Frais> { 

Context context; 
int layoutResourceId; 
LayoutInflater inflater; 
ArrayList<Frais> data= null; 

public FraisAdapter(Context context, int layoutResourceId, ArrayList<Frais> data) { 
    super(context, layoutResourceId, data); 
    this.context=context; 
    this.layoutResourceId=layoutResourceId; 
    this.data = data; 
    inflater = LayoutInflater.from(context); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) 
{ 
    View row = convertView; 
    FraisHolder holder; 

    if (row == null) 
    { 
     row = inflater.inflate(layoutResourceId, null); 
     holder = new FraisHolder(); 
     holder.title = (TextView) row.findViewById(R.id.frais_item_title); 
     holder.image = (ImageView) row.findViewById(R.id.frais_item_imageview); 
     row.setTag(holder); 
    } 
    else 
    { 
     holder = (FraisHolder) row.getTag(); 
    } 

    Frais frais = data.get(position); 

    //holder.image.setImageURI(frais.getImage()); 
    holder.image.setImageBitmap(Utilities.decodeSampledBitmap(frais.getImage().getPath(),16,16)); 
    holder.title.setText(frais.getNom()); 

    return row; 
} 

static class FraisHolder { 
    public TextView title; 
    public ImageView image; 
} 

}

Utilities.java

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; 
} 

public static Bitmap decodeSampledBitmap(String path, int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(path); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(path); 

} 

И, наконец, моя ошибка:

java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 10359328 free bytes and 9MB until OOM 
                     at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
                     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
                     at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635) 
                     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611) 
                     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391) 
                     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417) 
                     at ip1a.metier.Utilities.decodeSampledBitmap(Utilities.java:58) 
                     at ip1a.adapters.FraisAdapter.getView(FraisAdapter.java:59) 
                     at android.widget.AbsListView.obtainView(AbsListView.java:2346) 
                     at android.widget.ListView.makeAndAddView(ListView.java:1876) 
                     at android.widget.ListView.fillDown(ListView.java:702) 
                     at android.widget.ListView.fillSpecific(ListView.java:1367) 
                     at android.widget.ListView.layoutChildren(ListView.java:1696) 
                     at android.widget.AbsListView.onLayout(AbsListView.java:2148) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336) 
                     at android.widget.FrameLayout.onLayout(FrameLayout.java:273) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336) 
                     at android.widget.FrameLayout.onLayout(FrameLayout.java:273) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122) 
                     at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42) 
                     at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1192) 
                     at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1187) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336) 
                     at android.widget.FrameLayout.onLayout(FrameLayout.java:273) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743) 
                     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586) 
                     at android.widget.LinearLayout.onLayout(LinearLayout.java:1495) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336) 
                     at android.widget.FrameLayout.onLayout(FrameLayout.java:273) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743) 
                     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586) 
                     at android.widget.LinearLayout.onLayout(LinearLayout.java:1495) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336) 
                     at android.widget.FrameLayout.onLayout(FrameLayout.java:273) 
                     at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2934) 
                     at android.view.View.layout(View.java:16639) 
                     at android.view.ViewGroup.layout(ViewGroup.java:5437) 
                     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171) 
                     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931) 
                    at androi 
+0

Вы не пытались изменить размер битма? aps, прежде чем добавлять их в свой список? –

ответ

0

Попробуйте добавить как этот

options.inPurgeable=true; //It will clear the cache when it overflows 

в decodeSampledBitmap() функции

Или второй способ, чтобы изменить размер растрового изображения с помощью

Bitmap.createScaledBitmap() 
Смежные вопросы