java - Recyclerview 内存不足错误(使用 Volley)

标签 java android json android-recyclerview android-volley

我正在使用 Volley 从 json 数组中获取数据,但在加载更多数据时我遇到了一些实际问题!我在我的 SQL 查询 中设置了 OFFSET 以发送 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);
    }
}
}

列表.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;
    }
}

我的 Activity :

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 个项目(相同的项目)。并在上下滚动一些应用程序后崩溃。

最佳答案

我会说发生这种情况是因为您禁用了 RecyclerView 的嵌套滚动并将 RecyclerView 放在 NestedScrollView 中导致RecyclerView 一次加载所有项目并且不回收任何导致 OOM 和性能问题的 View 。

解决方法:

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

关于java - Recyclerview 内存不足错误(使用 Volley),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50776083/

相关文章:

android - 使用操作栏夏洛克

android - Intent.EXTRA_INITIAL_INTENTS 不会在选择器中添加应用

javascript - 是否应该引用 Javascript 对象键?

java - 如何使用 Flexjson JSONDeserializer?

java - 将 json 对象添加到 Java HttpGet 请求到 C# WebApi

线程 "main"java.lang.NumberFormatException : For input string: "" 中的 JavaScript 到 Java 异常

java - 修改或生成Android resources.arsc和编译 list

java - exec,文件位置问题

java创建带有页眉和页脚的pdf

android - Cordova ubuntu : An error occurred while listing Android targets