setAdapter() 在 android studio 中使 android 应用程序崩溃
Posted
技术标签:
【中文标题】setAdapter() 在 android studio 中使 android 应用程序崩溃【英文标题】:setAdapter() crashes android app in android studio 【发布时间】:2021-12-22 15:02:24 【问题描述】:我正在关注本教程 (https://www.youtube.com/watch?v=hDSVInZ2JCs&t=3615s&ab_channel=SoftwareandProgrammingwithProfessorSluiter)
一切都很好,直到我尝试这行代码:
lv_productList.setAdapter(productArrayAdapter);
然后应用程序崩溃。我在网上看了很多东西,但我超级卡住了
这是问题区域
btn_viewAll.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
DataBaseHelper dataBaseHelper = new DataBaseHelper(MainActivity.this);
List<ProductModel> all = dataBaseHelper.getAll();
ArrayAdapter productArrayAdapter = new ArrayAdapter<ProductModel>(MainActivity.this, android.R.layout.simple_list_item_1, all);
lv_productList.setAdapter(productArrayAdapter);
Toast.makeText(MainActivity.this, all.toString(), Toast.LENGTH_SHORT).show();
);
这是我的完整代码
MainActivity.java
package com.example.sqldemo;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.List;
public class MainActivity extends AppCompatActivity
//reference to all buttons and controls on the layout
Button btn_add, btn_viewAll;
EditText et_name, et_number;
ListView lv_productList;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_add = findViewById(R.id.btn_add);
btn_viewAll = findViewById(R.id.btn_viewAll);
et_name = findViewById(R.id.et_name);
et_number = findViewById(R.id.et_number);
btn_add.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
ProductModel productModel;
try
productModel = new ProductModel(-1, et_name.getText().toString(), Integer.parseInt(et_number.getText().toString()));
Toast.makeText(MainActivity.this, productModel.toString(), Toast.LENGTH_SHORT).show();
catch(Exception err)
Toast.makeText(MainActivity.this, "Error creating product", Toast.LENGTH_SHORT).show();
productModel = new ProductModel(-1, "error", 0);
DataBaseHelper dataBaseHelper = new DataBaseHelper(MainActivity.this);
boolean success = dataBaseHelper.addOne(productModel);
Toast.makeText(MainActivity.this, "Success! Product has been added to the database :)", Toast.LENGTH_SHORT).show();
);
btn_viewAll.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
DataBaseHelper dataBaseHelper = new DataBaseHelper(MainActivity.this);
List<ProductModel> all = dataBaseHelper.getAll();
ArrayAdapter productArrayAdapter = new ArrayAdapter<ProductModel>(MainActivity.this, android.R.layout.simple_list_item_1, all);
lv_productList.setAdapter(productArrayAdapter);
Toast.makeText(MainActivity.this, all.toString(), Toast.LENGTH_SHORT).show();
);
DataBaseHelper.java
package com.example.sqldemo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class DataBaseHelper extends SQLiteOpenHelper
public static final String PRODUCT_TABLE = "PRODUCT_TABLE";
public static final String COLUMN_PRODUCT_NAME = "PRODUCT_NAME";
public static final String COLUMN_PRODUCT_NUMBER = "PRODUCT_AGE";
public static final String COLUMN_ID = "ID";
public DataBaseHelper(@Nullable Context context)
super(context, "Products.db", null, 1);
//this is called the first item a database is accessed. used to create a new database
@Override
public void onCreate(SQLiteDatabase db)
String createTableStatement = "CREATE TABLE " + PRODUCT_TABLE + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_PRODUCT_NAME + " TEXT, " + COLUMN_PRODUCT_NUMBER + " INT)";
db.execSQL(createTableStatement);
//this is called if the database version number changes. It prevents previous users apps from breaking when the database is updated
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
public boolean addOne(ProductModel productModel)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_PRODUCT_NAME, productModel.getName());
cv.put(COLUMN_PRODUCT_NUMBER, productModel.getNumber());
//long insert returns positive in data insertion was successful, and negative if it was not
long insert = db.insert(PRODUCT_TABLE, null, cv);
if (insert == -1)
return false;
else
return true;
public List<ProductModel> getAll()
List<ProductModel> returnList = new ArrayList<>();
// get data from the database
String queryString = "SELECT * FROM " + PRODUCT_TABLE;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(queryString, null);
//move the cursor to the first set of data and check if anything was returned
if (cursor.moveToFirst())
// loop through the cursor (result set) and create new product objects. Put them into the return list (defined above)
do
int productID = cursor.getInt(0);
String productName = cursor.getString(1);
int productNumber = cursor.getInt(2);
ProductModel newProduct = new ProductModel(productID, productName, productNumber);
returnList.add(newProduct);
while (cursor.moveToNext());
else
//if no results from database, don't add anything to the list.
cursor.close();
db.close();
return returnList;
ProductModel.java
package com.example.sqldemo;
//declare a new public class/object with 3 variables
public class ProductModel
private int id;
private String name;
private int number;
//constructor
public ProductModel(int id, String name, int number)
this.id = id;
this.name = name;
this.number = number;
public ProductModel()
// toString is necessary for printing the contents of a class object
@Override
public String toString()
return "ProductModel" +
"id=" + id +
", name='" + name + '\'' +
", number=" + number +
'';
//getters and setters
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public int getNumber()
return number;
public void setNumber(int number)
this.number = number;
> Blockquote
【问题讨论】:
提示:你在哪里设置lv_productList
的值?
快速猜测这可能是您在onclick
中的ArrayAdapter productArrayAdapter = new ...
尝试将ArrayAdapter productArrayAdapter
定义为一个全局值,就像您为lv_productList
所做的那样
您是否在 XML 文件中定义了 lv_productList
ID?
@enzo 编辑:哦,你的意思是在activity_main.xml 中?是的,它在里面" app:layout_constraintTop_toBottomOf="@+id/btn_viewAll" />
您应该始终查看 logcat 窗口,这通常会为您提供有关导致崩溃的确切原因的更多详细信息。
【参考方案1】:
您可以简单地将 RecyclerView 更改为 ListView。
或者
如果你想使用 RecyclerView,你必须创建一个自定义的 Recyclerview Adapter。 这里是初学者友好指南:https://medium.com/@suhanshupatel/recyclerview-in-android-for-beginner-cfbc132a0dec
【讨论】:
以上是关于setAdapter() 在 android studio 中使 android 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio 无法识别“setAdapter()”方法
Android:尝试在空对象引用上调用虚拟方法“void android.widget.ListView.setAdapter(android.widget.ListAdapter)”
Android - 片段中的 setAdapter [重复]
尝试在空对象引用上调用虚拟方法“void android.support.v4.view.ViewPager.setAdapter(android.support.v4.view.PagerAdapt
当我调用 setAdapter() 到 recycleView 时,我的 Android 应用程序意外退出
method ‘void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)‘ on a null object refe