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