Recyclerview Out of Memory错误(使用Volley)

时间:2018-06-09 16:00:26

标签: java android json android-recyclerview android-volley

我正在使用Volley从json数组中获取数据,而我在加载更多数据时遇到了一些实际问题!我已在OFFSET设置SQL Query以发送10项,每次Android发送page号码以获取更多数据!它工作得很好,我已经用Postman应用程序测试了我的PHP代码,没有问题!我想我的recyclerview或我从服务器获取数据导致内存不足问题的方式出了问题!所以,如果你看看我的代码,你可能会发现问题!
这是我的代码:

我的适配器:

public class ReviewsAdapter extends RecyclerView.Adapter<ReviewsAdapter.ReviewsHolder> {
private Context context;
private ArrayList<ReviewsList> reviewsList;

public ReviewsAdapter(ArrayList<ReviewsList> reviewsList, Context context) {
    this.reviewsList = reviewsList;
    this.context = context;
}

@Override
public ReviewsAdapter.ReviewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new ReviewsAdapter.ReviewsHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_reviews, parent, false));
}

private float f;

@Override
public void onBindViewHolder(ReviewsAdapter.ReviewsHolder holder, int position) {
    holder.userName.setText(reviewsList.get(position).getSentBy());
    for (f = 0.0f; f <= 5.0f; f += 0.5f) {
        if (f == Float.valueOf(reviewsList.get(position).getRate())) {
            holder.ratingBar.setRating(f);
        }
    }
    holder.date.setText(reviewsList.get(position).getDate());
    holder.Ctext.setText(reviewsList.get(position).getCText());
}

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

class ReviewsHolder extends RecyclerView.ViewHolder {
    TextView userName, date;
    JustifiedTextView Ctext;
    RatingBar ratingBar;

    ReviewsHolder(View view) {
        super(view);
        userName = view.findViewById(R.id.userName);
        ratingBar = view.findViewById(R.id.commentRate);
        date = view.findViewById(R.id.commentDate);
        Ctext = view.findViewById(R.id.commentText);
    }
}
}

List.java:

public class ReviewsList {
    private int Cid;
    private String sentBy, rate, date, Ctext;

    public ReviewsList(int Cid, String sentBy, String rate, String date, String Ctext) {
        this.sentBy = sentBy;
        this.rate = rate;
        this.date = date;
        this.Ctext = Ctext;
        this.Cid = Cid;
    }

    public String getSentBy() {
        return sentBy;
    }
    public String getRate() {
        return rate;
    }
    public String getDate() {
        return date;
    }
    public String getCText() {
        return Ctext;
    }
}

我的活动:

public class ReviewsActivity extends AppCompatActivity {

private int page = 0;
private boolean itShouldLoadMore = true;
private RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
private ArrayList<ReviewsList> reviewsLists;
private ReviewsAdapter reviewsAdapter;

TextView noMoreData;
NestedScrollView nestedScrollView;

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

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

    noMoreData = findViewById(R.id.NoMoreDataTxt);
    reviewsLists = new ArrayList<>();
    reviewsAdapter = new ReviewsAdapter(reviewsLists, getApplicationContext());
    linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView = findViewById(R.id.RecyclerView);
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);
    recyclerView.setAdapter(reviewsAdapter);

    firstLoadData();

    recyclerView.setNestedScrollingEnabled(false);
    nestedScrollView = findViewById(R.id.nestedScrollView);
    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            int totalItemCount = linearLayoutManager.getItemCount();
            int lastVisible = linearLayoutManager.findLastVisibleItemPosition();

            boolean endHasBeenReached = lastVisible + 5 >= totalItemCount;
            if (totalItemCount > 0 && endHasBeenReached) {
                loadMore();
            }
        }
    });

    recyclerView.setNestedScrollingEnabled(false);
}

public void firstLoadData() {
    String url = "https://oh-music.ir/parastar/get_reviews.php?page=1" + "&nurseId=" + theId;
    itShouldLoadMore = false;
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {
            itShouldLoadMore = true;
            if (response.length() <= 0) {
                noMoreData.setVisibility(View.VISIBLE);
                return;
            }
            for (int i = 0; i < response.length(); i++) {
                try {
                    JSONObject jsonObject = response.getJSONObject(i);

                    int id = jsonObject.getInt("id");
                    String sent_by = jsonObject.getString("sent_by");
                    String rate = jsonObject.getString("rate");
                    String date = jsonObject.getString("date");
                    String text = jsonObject.getString("text");

                    reviewsLists.add(new ReviewsList(id, sent_by, rate, date, text));
                    reviewsAdapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            itShouldLoadMore = true;
            String message = "";
            new VolleyErrorHandler(getApplicationContext(), error, message);
        }
    });

    //Pay Attention to this line is this causing the crashing?
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsonArrayRequest);
}

private void loadMore() {
    String url = "https://oh-music.ir/parastar/get_reviews.php?action=loadmore&page=" + String.valueOf(page++) + "&nurseId=" + theId;
    itShouldLoadMore = false;
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {
            itShouldLoadMore = true;
            if (response.length() <= 0) {
                noMoreData.setVisibility(View.VISIBLE);
                return;
            }

            for (int i = 0; i < response.length(); i++) {
                try {
                    JSONObject jsonObject = response.getJSONObject(i);
                    int id = jsonObject.getInt("id");
                    String sent_by = jsonObject.getString("sent_by");
                    String rate = jsonObject.getString("rate");
                    String date = jsonObject.getString("date");
                    String text = jsonObject.getString("text");

                    reviewsLists.add(new ReviewsList(id, sent_by, rate, date, text));
                    reviewsAdapter.notifyDataSetChanged();

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            itShouldLoadMore = true;
            String message = "";
            new VolleyErrorHandler(getApplicationContext(), error, message);
        }
    });

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsonArrayRequest);
}

@Override
public void onBackPressed() {
    if (drawer.isDrawerOpen()) {
        drawer.closeDrawer();
    } else {
        super.onBackPressed();
    }
}
}

正如你可能要求logcat错误,我要说有很多错误但不是红色!以下是其中一些:

它是这样开始的: enter image description here

对于大约100行代码继续这样: enter image description here

以这些结尾: enter image description here

我将非常感谢您的帮助♥感谢您的时间......

编辑:我要说当recyclerview到达终点并尝试加载更多数据时,它会再次重现之前的项目!例如,如果有7个项目,则加载7个项目(相同的项目)。在上下滚动之后,应用程序崩溃了。

1 个答案:

答案 0 :(得分:1)

我会说这是因为您要禁用RecyclerView的嵌套滚动,并将RecyclerView放在NestedScrollView内导致RecyclerView到一次加载所有项目,而不是回收任何导致OOM和性能问题的视图。

解决方案:

  1. 删除NestedScrollView并直接在RecyclerView上设置ScrollListener。
  2. 删除recyclerView.setNestedScrollingEnabled(false);