#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);