在处理 firebase 数据库和 searchview 时出现致命异常
Getting a fatal exception while working on firebase database and searchview
我正在尝试将 Searchview 与 Recylerview 和 firebase 数据库一起使用,我一直在关注一些教程并且我已经正确地观看了视频所以我不知道为什么我会收到错误,我有三个 classn 一个是适配器,一个是辅助器,一个是主要的,我得到的错误是:
2021-05-12 03:16:12.931 31658-31658/com.example.search E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.search, PID: 31658
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.search.Deal
在以下行中:
list.add(ds.getValue(Deal.class));
这是我的主activity:
package com.example.search;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Deal> list;
RecyclerView recyclerView;
SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref = FirebaseDatabase.getInstance().getReference().child("medicines");
recyclerView = findViewById(R.id.rv);
searchView = findViewById(R.id.searchview);
}
@Override
protected void onStart() {
super.onStart();
if(ref != null){
ref.addValueEventListener(new ValueEventListener() {
@NonNull
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : snapshot.getChildren()){
list.add(ds.getValue(Deal.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if (searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str) {
if (!str.equals("")){
ArrayList<Deal>myList = new ArrayList<>();
for (Deal object : list){
if(object.getDisease().toLowerCase().contains(str.toLowerCase())){
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
}
}
这是我的“帮手”class,我称之为交易:
package com.example.search;
public class Deal {
private String disease, medication;
public Deal() {
}
public Deal(String disease, String medication) {
this.disease = disease;
this.medication = medication;
}
public String getDisease() {
return disease;
}
public void setDisease(String disease) {
this.disease = disease;
}
public String getMedication() {
return medication;
}
public void setMedication(String medication) {
this.medication = medication;
}
}
这是我的适配器class:
package com.example.search;
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 java.util.ArrayList;
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder> {
ArrayList<Deal> list;
public AdapterClass(ArrayList<Deal> list){
this.list = list;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_holder, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.disease.setText(list.get(position).getDisease());
holder.medicine.setText(list.get(position).getMedication());
}
@Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView disease, medicine;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
disease = itemView.findViewById(R.id.disease);
medicine = itemView.findViewById(R.id.medication);
}
}
}
这是我的主要 activity 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/searchview"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:padding="10dp"
android:layout_margin="5dp"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:autofillHints="Search here"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
</LinearLayout>
和我的卡片视图布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/disease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:padding="10dp"
android:text="disease_name" />
<TextView
android:id="@+id/medication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="solution"
android:padding="10dp"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"
/>
</androidx.cardview.widget.CardView>
这就是整个应用程序的全部内容,所以我不明白为什么应用程序一直崩溃,这就是我的 firebase 数据库的样子
{
"medicines" : {
"disease" : "maleria",
"medication" : "aspirin"
}
}
我之前遇到过不同的异常,我更改了数据库中的规则并调试了应用程序,现在我发现这个错误已经持续了两个小时,老实说,我没有任何线索,我已经尝试过检查我是否写错了,如果我在 helper(deal)class 中添加的名称与 firebase 等中的名称匹配,他们这样做我不知道
由于您的 Deal
class 定义了属性 disease
和 mediation
,因此 medicines
下似乎只有一个 Deal
对象。
因此,对于您当前的数据,您不应该在 onDataChange
中对 getChildren
使用循环,只需执行以下操作:
public void onDataChange(@NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
list.add(snapshot.getValue(Deal.class));
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
我正在尝试将 Searchview 与 Recylerview 和 firebase 数据库一起使用,我一直在关注一些教程并且我已经正确地观看了视频所以我不知道为什么我会收到错误,我有三个 classn 一个是适配器,一个是辅助器,一个是主要的,我得到的错误是:
2021-05-12 03:16:12.931 31658-31658/com.example.search E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.search, PID: 31658
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.search.Deal
在以下行中:
list.add(ds.getValue(Deal.class));
这是我的主activity:
package com.example.search;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Deal> list;
RecyclerView recyclerView;
SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref = FirebaseDatabase.getInstance().getReference().child("medicines");
recyclerView = findViewById(R.id.rv);
searchView = findViewById(R.id.searchview);
}
@Override
protected void onStart() {
super.onStart();
if(ref != null){
ref.addValueEventListener(new ValueEventListener() {
@NonNull
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : snapshot.getChildren()){
list.add(ds.getValue(Deal.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if (searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str) {
if (!str.equals("")){
ArrayList<Deal>myList = new ArrayList<>();
for (Deal object : list){
if(object.getDisease().toLowerCase().contains(str.toLowerCase())){
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
}
}
这是我的“帮手”class,我称之为交易:
package com.example.search;
public class Deal {
private String disease, medication;
public Deal() {
}
public Deal(String disease, String medication) {
this.disease = disease;
this.medication = medication;
}
public String getDisease() {
return disease;
}
public void setDisease(String disease) {
this.disease = disease;
}
public String getMedication() {
return medication;
}
public void setMedication(String medication) {
this.medication = medication;
}
}
这是我的适配器class:
package com.example.search;
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 java.util.ArrayList;
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder> {
ArrayList<Deal> list;
public AdapterClass(ArrayList<Deal> list){
this.list = list;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_holder, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.disease.setText(list.get(position).getDisease());
holder.medicine.setText(list.get(position).getMedication());
}
@Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView disease, medicine;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
disease = itemView.findViewById(R.id.disease);
medicine = itemView.findViewById(R.id.medication);
}
}
}
这是我的主要 activity 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/searchview"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:padding="10dp"
android:layout_margin="5dp"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:autofillHints="Search here"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
</LinearLayout>
和我的卡片视图布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/disease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:padding="10dp"
android:text="disease_name" />
<TextView
android:id="@+id/medication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="solution"
android:padding="10dp"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"
/>
</androidx.cardview.widget.CardView>
这就是整个应用程序的全部内容,所以我不明白为什么应用程序一直崩溃,这就是我的 firebase 数据库的样子
{
"medicines" : {
"disease" : "maleria",
"medication" : "aspirin"
}
}
我之前遇到过不同的异常,我更改了数据库中的规则并调试了应用程序,现在我发现这个错误已经持续了两个小时,老实说,我没有任何线索,我已经尝试过检查我是否写错了,如果我在 helper(deal)class 中添加的名称与 firebase 等中的名称匹配,他们这样做我不知道
由于您的 Deal
class 定义了属性 disease
和 mediation
,因此 medicines
下似乎只有一个 Deal
对象。
因此,对于您当前的数据,您不应该在 onDataChange
中对 getChildren
使用循环,只需执行以下操作:
public void onDataChange(@NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
list.add(snapshot.getValue(Deal.class));
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}