Адаптер не подключен; пропуск компоновки при использовании volley

#java #android #android-studio #android-recyclerview

Вопрос:

я использую volley здесь,чтобы получать данные с сервера xampp через свой api(отлично работает на postman), но при запуске кода, заданный тост onErrorResponse отображается на дисплее, как только приложение открывается, и приложение не аварийно завершает работу. прочитал много решений этой проблемы ,многие из них были связаны с фрагментами..я не использовал фрагменты… также в моем коде я думаю ,что когда я вызвал метод setAdapter в recyclerview, я чуть выше определил MyAdapter

 MyAdapter myAdapter = new MyAdapter(data);
recyclerView.setAdapter(myAdapter);
 

главная activity.java

 package com.example.poetryapp;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.example.poetryapp.adapter.MyAdapter;
import com.example.poetryapp.model.PoetryModel;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.poetry_recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));


        loaddata();
    }

    private void loaddata() {

        String url = "http://192.168.137.198/poetryapi/getPoetryRead.php.php";

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                GsonBuilder gsonBuilder = new GsonBuilder();
                Gson gson = gsonBuilder.create();

                PoetryModel data[]=gson.fromJson(response,PoetryModel[].class);

                MyAdapter myAdapter = new MyAdapter(data);
                recyclerView.setAdapter(myAdapter);
                myAdapter.notifyDataSetChanged();

                Log.e("success",response);
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_LONG).show();
            }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> params=new HashMap<>();
                return params;
            }
        };
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);



    }
    }
 

MyAdapter.java

 package com.example.poetryapp.adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.poetryapp.R;
import com.example.poetryapp.model.PoetryModel;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.viewHolder> {

    PoetryModel data[];

    public MyAdapter(PoetryModel[] data) {
        this.data = data;
    }

    @NonNull
    @Override
    public viewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.poetry_list_view,parent,false);
        return new viewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull viewHolder holder, int position) {
        holder.t1_name.setText(data[position].getPoet_name());
        holder.t2_data.setText(data[position].getPoetry_data());
        holder.t3_date_time.setText(data[position].getDate_time());
    }

    @Override
    public int getItemCount() {
        return data.length;
    }

    class viewHolder extends RecyclerView.ViewHolder{
        TextView t1_name,t2_data,t3_date_time;
        public viewHolder(@NonNull View itemView) {
            super(itemView);

            t1_name=itemView.findViewById(R.id.tv_poetName);
            t2_data=itemView.findViewById(R.id.tv_poetryData);
            t3_date_time=itemView.findViewById(R.id.tv_poet_dateTime);

        }
    }


}

 

main.xml

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@ id/main_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/black" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/main_toolbar"
        android:orientation="vertical"
        >

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@ id/poetry_recyclerView"
            />

    </LinearLayout>

</RelativeLayout>
 

logcat error message

 2021-09-09 09:38:45.963 29496-29496/com.example.poetryapp E/RecyclerView: No adapter attached; skipping layout
2021-09-09 09:38:46.004 29496-29496/com.example.poetryapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.poetryapp, PID: 29496
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
        at com.google.gson.Gson.fromJson(Gson.java:944)
        at com.google.gson.Gson.fromJson(Gson.java:897)
        at com.google.gson.Gson.fromJson(Gson.java:846)
        at com.google.gson.Gson.fromJson(Gson.java:817)
        at com.example.poetryapp.MainActivity$1.onResponse(MainActivity.java:53)
        at com.example.poetryapp.MainActivity$1.onResponse(MainActivity.java:46)
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7868)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:981)
     Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
        at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:349)
        at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70)
        at com.google.gson.Gson.fromJson(Gson.java:932)
        at com.google.gson.Gson.fromJson(Gson.java:897) 
        at com.google.gson.Gson.fromJson(Gson.java:846) 
        at com.google.gson.Gson.fromJson(Gson.java:817) 
        at com.example.poetryapp.MainActivity$1.onResponse(MainActivity.java:53) 
        at com.example.poetryapp.MainActivity$1.onResponse(MainActivity.java:46) 
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82) 
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29) 
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7868) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:981) 

 

мой URL-адрес возвращает это

 {
    "status": "1",
    "message": "record is not empty",
    "data": [
        {
            "id": "1",
            "poetry_data": "shdoqw djwaiood aand od sodnh asisd d ashd asidhas das das doaisdhas dsa d as diwdhw xs dw wh codfj e",
            "poet_name": "abcd efg",
            "date_time": "2021-09-02 08:32:10"
        },
        {
            "id": "2",
            "poetry_data": "updating this",
            "poet_name": "abc",
            "date_time": "2021-09-04 10:38:22"
        },
        {
            "id": "4",
            "poetry_data": "aaaaaaaaaaaa bbbbbbbbbbbbb cccccccccccccc",
            "poet_name": "abc",
            "date_time": "2021-09-02 10:11:08"
        },
        {
            "id": "5",
            "poetry_data": "aaaaaaaaaaaaaaaaaaaaa",
            "poet_name": "aa",
            "date_time": "2021-09-03 10:16:08"
        },
        {
            "id": "6",
            "poetry_data": "aaaaaaaaaaaaaaaaaaaaa",
            "poet_name": "aa",
            "date_time": "2021-09-03 10:16:22"
        },
        {
            "id": "7",
            "poetry_data": "aaaaaaaaaaaaaaaaaaaaa",
            "poet_name": "aa",
            "date_time": "2021-09-03 10:17:04"
        },
        {
            "id": "8",
            "poetry_data": "",
            "poet_name": "",
            "date_time": "2021-09-06 09:19:39"
        },
        {
            "id": "9",
            "poetry_data": "",
            "poet_name": "",
            "date_time": "2021-09-06 09:23:38"
        },
        {
            "id": "10",
            "poetry_data": "",
            "poet_name": "",
            "date_time": "2021-09-06 09:24:00"
        },
        {
            "id": "11",
            "poetry_data": "bhdjasvjguuuuuuuuuuuuuuuu",
            "poet_name": "nameisname",
            "date_time": "2021-09-06 09:29:59"
        },
        {
            "id": "12",
            "poetry_data": "bhdjasvjguuuuuuuuuuuuuuuu",
            "poet_name": "abara",
            "date_time": "2021-09-06 09:42:43"
        },
        {
            "id": "13",
            "poetry_data": "bhdjasvjguuuuuuuuuuuuuuuu",
            "poet_name": "kkkkkkkhgvghytu",
            "date_time": "2021-09-06 09:52:21"
        }
    ]
}
 

вторая ошибка связана с gson, но я не знаю, как правильно написать ее, чтобы проанализировать json в gson для структуры, которую возвращает мой URL-адрес.

Спасибо!

Ответ №1:

ты пробовал

 myAdapter.notifyDataSetChanged()
 

после этой линии в вашей основной деятельности?

 recyclerView.setAdapter(myAdapter);
 

Комментарии:

1. пробовал сейчас recyclerView.setAdapter(myAdapter); myAdapter.notifyDataSetChanged(); ,но теперь в моем журнале ошибок появилась новая ошибка, обновленный код выше, сэр

2. Ну, теперь ошибка с получением данных из api-это ошибка синтаксического анализа, которая означает, что вы получаете данные с неправильным ответом, потому что ваши фактические данные внутри большого объекта, который вы используете. ваши данные . Теперь я сказал это просто для того, чтобы объяснить, почему вы столкнулись с этой ошибкой и чтобы избежать ее в будущем. Теперь вы можете устранить эту ошибку, следуя тому, что сказал @Abhishek Ippakayal. И в будущем вы можете зайти на этот сайт, чтобы написать свой ответ. jsonschema2pojo.org

3. Также просто небольшой совет написать более практичный код, чтобы следовать структуре MVVM с репозиториями и доработать модель представления.Кроме того, взгляните на привязку представления. Получить представления проще, чем findviewbyid. У Google есть отличный пример, что поначалу нормально не понимать всего этого к тому времени, когда вы это сделаете. Удачи!

Ответ №2:

Увидев ваш журнал ошибок и ваш json-ответ api, вы неправильно его анализируете. Ваш класс ответов должен выглядеть следующим образом.

 class PoetryResponse() {
   @Serializable("status")
   String status;

   @Serializable("message")
   String message;

   @Serializable("data")
   Poetry[] data;

}
 

Ваш класс объектов данных

 class Poetry() {
 @Serializable("id")
   String id;

   @Serializable("poetry_data")
   String poetryData;

   @Serializable("poet_name")
   String poetName;
   
   @Serializable("date_time")
   String dateTime;
}
 

Получите ответ от json с приведенным ниже кодом

 PoetryResponse poetryResponse = gson.fromJson(response,PoetryResponse.class);
 

Теперь передайте список стихов, как показано ниже, в свой адаптер

 MyAdapter myAdapter = new MyAdapter(poetryResponse.data);