Recyclerview Out of Memory Error (используется залп) - PullRequest
0 голосов
/ 09 июня 2018

Я использую Volley для извлечения данных из массива json, и у меня возникают реальные проблемы с загрузкой большего количества данных!Я установил OFFSET в моем SQL Query для отправки 10 элементов, каждый раз, когда Android отправляет номер page, чтобы получить больше данных!Он отлично работает, и я уже проверил свои php-коды с приложением Postman, и с этим проблем нет!Я думаю, что-то не так с моим 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

Я буду очень признателен за вашу помощь ♥ Спасибо за ваше время ...

РЕДАКТИРОВАТЬ: ЯЯ хочу сказать, что когда утилита переработчика достигает конца и пытается загрузить больше данных, она снова воспроизводит предыдущие элементы!например, если есть 7 предметов, он загружает еще 7 предметов (таких же предметов).и после некоторой прокрутки вверх и вниз приложение вылетает.

1 Ответ

0 голосов
/ 09 июня 2018

Я бы сказал, что это происходит потому, что вы отключаете вложенную прокрутку RecyclerView, а также помещаете RecyclerView в NestedScrollView, в результате чего RecyclerView загружает все элементы одновременно и не перерабатываетлюбые представления, которые приводят к OOM и проблемам с производительностью.

Решение:

  1. Удалите NestedScrollView и установите ScrollListener непосредственно в RecyclerView.
  2. Удалить recyclerView.setNestedScrollingEnabled(false);
...