Robin
Robin

Reputation: 1547

App crashes when using RecyclerView

This app is to show a recycler view on screen and it crashes right on launch. The logcat:

:16.836 8259-8259/com.robyn.frog E/AndroidRuntime: FATAL EXCEPTION: main
                                                          Process: com.robyn.frog, PID: 8259
                                                          java.lang.OutOfMemoryError: Failed to allocate a 512174316 byte allocation with 16777120 free bytes and 227MB until OOM
                                                              at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                              at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
                                                              at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
                                                              at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
                                                              at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)
                                                              at android.content.res.Resources.loadDrawableForCookie(Resources.java:2596)
                                                              at android.content.res.Resources.loadDrawable(Resources.java:2503)
                                                              at android.content.res.Resources.getDrawable(Resources.java:864)
                                                              at android.content.Context.getDrawable(Context.java:403)
                                                              at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:353)
                                                              at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:201)
                                                              at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:189)
                                                              at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100)
                                                              at android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:54)
                                                              at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:66)
                                                              at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:56)
                                                              at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106)
                                                              at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1026)
                                                              at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1083)
                                                              at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:725)
                                                              at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
                                                              at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
                                                              at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                                                              at com.robyn.frog.RecyclerFragment$FrogHolder.<init>(RecyclerFragment.java:0)
                                                              at com.robyn.frog.RecyclerFragment$FrogAdapter.onCreateViewHolder(RecyclerFragment.java:72)
                                                              at com.robyn.frog.RecyclerFragment$FrogAdapter.onCreateViewHolder(RecyclerFragment.java:63)
                                                              at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6411)
                                                              at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5597)
                                                              at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5482)
                                                              at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5478)
                                                              at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2215)
                                                              at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1542)
                                                              at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1502)
                                                              at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
                                                              at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3625)
                                                              at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3354)
                                                              at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3886)
                                                              at android.view.View.layout(View.java:15737)
                                                              at android.view.ViewGroup.layout(ViewGroup.java:5041)
                                                              at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
                                                              at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1692)
                                                              at android.widget.LinearLayout.onLayout(LinearLayout.java:1468)
                                                              at android.view.View.layout(View.java:15737)
                                                              at android.view.ViewGroup.layout(ViewGroup.java:5041)
                                                              at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                              at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                              at android.view.View.layout(View.java:15737)
                                                              at android.view.ViewGroup.layout(ViewGroup.java:5041)
                                                              at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:434)
                                                            at android.view.View.lay

Main activity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = fm.findFragmentById(R.id.fragment_container);

    if (fragment == null) {
        fragment = new RecyclerFragment();
        fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
    }
}

}

Recycler fragment, containers the adapter and viewholder. After adding the updateUI method which uses the adapter, the app crashes.

public class RecyclerFragment extends Fragment {
private RecyclerView mRecyclerView;
private FrogAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.recycler, container, false);
    mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    updateUI();
    return view;
}

private void updateUI() {
    Pond pond = Pond.get(getActivity());
    List<Frog> frogs = pond.getFrogs();
    if (mAdapter == null) {
        mAdapter = new FrogAdapter(frogs);
        mRecyclerView.setAdapter(mAdapter);
    } else {
        mAdapter.notifyDataSetChanged();
    }
}

private class FrogHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private TextView mName;
    private TextView mWord;

    public FrogHolder(LayoutInflater inflater, ViewGroup parent) {
        super(inflater.inflate(R.layout.item, parent, false));
        itemView.setOnClickListener(this);

        mName = (TextView) itemView.findViewById(R.id.name);
        mWord = (TextView) itemView.findViewById(R.id.word);
    }

    @Override
    public void onClick(View v) {

    }
}


private class FrogAdapter extends RecyclerView.Adapter<FrogHolder>{
    private List<Frog> mFrogs;

    public FrogAdapter(List<Frog> frogs) {
        mFrogs = frogs;
    }
    @Override
    public FrogHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
        return new FrogHolder(layoutInflater, parent);
    }

    @Override
    public void onBindViewHolder(FrogHolder holder, int position) {
        Frog frog = mFrogs.get(position);
        holder.mName.setText(frog.getName());
        holder.mWord.setText(frog.getWord());
    }

    @Override
    public int getItemCount() {
        return mFrogs.size();
    }
}
}

This class makes up a list for the recycler view to show:

public class Pond {

public class Frog {
    private String mName;
    private String mWord;

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public String getWord() {
        return mWord;
    }

    public void setWord(String word) {
        mWord = word;
    }
}

private static Pond sPond;

private List<Frog> mFrogs;

public static Pond get(Context context) {
    if (sPond == null) {
        sPond = new Pond(context);
    }
    return sPond;
}

private Pond(Context context) {
    mFrogs = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        Frog frog = new Frog();
        frog.setName("Frog #" + i);
        frog.setWord("qqq");
        mFrogs.add(frog);
    }
}

public List<Frog> getFrogs() {
    return mFrogs;
}

}

layout files: activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.robyn.frog.MainActivity">

</LinearLayout>

recycler.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/recycler_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
</android.support.v7.widget.RecyclerView>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="10dp"
        app:srcCompat="@drawable/frog"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical">
        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"/>
        <TextView
            android:id="@+id/word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"/>
    </LinearLayout>
</LinearLayout>

Upvotes: 1

Views: 3326

Answers (1)

Eslam Ahmad
Eslam Ahmad

Reputation: 589

This problem caused when android start dealing with bitmaps. the main reason is lack of memory space and also, garbage collector cannot free some space.

You have two solutions for this situation:

  1. largeHeap

Go to your manifest file and add

android:largeHeap="true"

android:hardwareAccelerated="false"

inside application tag for example

   <application
     android:allowBackup="true"
     android:hardwareAccelerated="false"
     android:largeHeap="true"
     android:icon="@mipmap/ic_launcher"
     android:label="@string/app_name"
     android:supportsRtl="true"
     android:theme="@style/AppTheme">
  1. Using library like Universal Image Loader

https://github.com/nostra13/Android-Universal-Image-Loader

Upvotes: 2

Related Questions