为什么我的应用程序在尝试从sqlite数据库填充listview时崩溃了?

时间:2016-04-05 04:16:15

标签: android sqlite listview

当我尝试启动一个活动时,我的应用程序崩溃,我有一个listview。 我想把我的sqlite数据放到listview中。 崩溃报告:

04-05 14:11:47.479 2781-2781/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jonnyg.gardenapp/com.jonnyg.gardenapp.SeedSave}: java.lang.NullPointerException
                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
                                                 at android.app.ActivityThread.access$600(ActivityThread.java:141)
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
                                                 at android.os.Handler.dispatchMessage(Handler.java:99)
                                                 at android.os.Looper.loop(Looper.java:137)
                                                 at android.app.ActivityThread.main(ActivityThread.java:5041)
                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                 at java.lang.reflect.Method.invoke(Method.java:511)
                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                                                 at dalvik.system.NativeStart.main(Native Method)
                                              Caused by: java.lang.NullPointerException
                                                 at com.jonnyg.gardenapp.SeedSave.populateListView(SeedSave.java:197)
                                                 at com.jonnyg.gardenapp.SeedSave.onCreate(SeedSave.java:85)
                                                 at android.app.Activity.performCreate(Activity.java:5104)
                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
                                                 at android.app.ActivityThread.access$600(ActivityThread.java:141) 
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
                                                 at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                 at android.os.Looper.loop(Looper.java:137) 
                                                 at android.app.ActivityThread.main(ActivityThread.java:5041) 
                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                 at java.lang.reflect.Method.invoke(Method.java:511) 
                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
                                                 at dalvik.system.NativeStart.main(Native Method) 

DataBaseHelperClass相关代码:

public class DataBaseHelper extends SQLiteOpenHelper {
private static  final String DataBASE_NAME = "SeedSave.db";

private static  final String TABLE_NAME = "seed_table";
//public static  final String COL_1 = "ID";
private static  final String COL_2 = "SNAME";
private static  final String COL_3 = "STYPE";
private static  final String COL_4 = "SAMOUNT";



private static final int Version = 1;
private static Context myContext;



/*String name, SQLiteDatabase.CursorFactory factory, int version*/
public DataBaseHelper(Context context) {
    super(context, DataBASE_NAME, null, Version);
    //SQLiteDatabase db = this.getWritableDatabase();
    myContext = context;
}

创建表格本身

@Override
public void onCreate(SQLiteDatabase db) {

    db.execSQL("create table  " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, SNAME TEXT, STYPE TEXT,SAMOUNT INTEGER)");



}

在同一个数据库助手类中,我有查询

public Cursor getAllData(){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res = db.rawQuery("select ID AS _id,SNAME,STYPE,SAMOUNT from " + TABLE_NAME,null);
    /*if(res!=null){
        res.moveToFirst();
    }*/
    return  res;
}

更改SQLiteDatabase db = this.getWritableDatabase();到SQLiteDatabase db = this.getReadableDatabase();没有明显的影响。

现在在我的活动中我想运行列表视图,我在其中调用此方法。

private void populateListView(){
    ListView myList_view;
    myDb = new DataBaseHelper(this);
    Cursor res = myDb.getAllData();

    SeedSave mySeed = new SeedSave();
    String[] from = new String[]{null,mySeed.editSname.toString(),
            mySeed.editStype.toString(),mySeed.editSamount.toString()};

    int[] to = new int[]{R.id.textViewID,R.id.textViewName,R.id.textViewSType,R.id.textViewAmount
            };
    SimpleCursorAdapter myScursorAdapter;
    myScursorAdapter = new SimpleCursorAdapter(getBaseContext(),
            R.layout.item_layout_seed, res, from,to,0);

    myList_view = (ListView)findViewById(R.id.listViewTest);
    myList_view.setAdapter(myScursorAdapter);
}

我认为探测器位于自定义布局,或者From和to变量没有正确排列所需的数据。

现在为我的种子表,我将值传递给构造函数以添加数据。

public class Seed_Table {

private int _id;
private String _seedName;
private String _seedType;
//private String _amount;
private int _amount;

public Seed_Table(){

}
public Seed_Table(String sname, String stype, int amount) {
    this._seedName = sname;
    this._seedType = stype;
    this._amount = amount;
}



public void set_id(int _id) {
    this._id = _id;
}

public void set_seedName(String _seedName) {
    this._seedName = _seedName;
}

public void set_seedType(String _seedType) {
    this._seedType = _seedType;
}

public void set_amount(int _amount) {
    this._amount = _amount;
}

public int get_id() {

    return _id;
}

public String get_seedName() {
    return _seedName;
}

public int get_amount() {
    return _amount;
}

public String get_seedType() {
    return _seedType;
}

}

以下是我的自定义线性布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewID" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewName" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewSType" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewAmount"
    android:layout_marginBottom="30dp"/>

/&GT;

是否有使数据视图成功的问题?当orientation =垂直时。这应该是横向的吗?我希望如何在下面查看数据: UI of layout

列表视图位于我想要使用的活动上。下面是listview本身的代码:

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:id="@+id/listViewTest"

    android:layout_below="@+id/btnAdd"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

我还在添加如何将数据添加到数据库以防可能有所帮助。 在dataBaseHelper类中,我将值传递给Seed_Table的构造函数:

public void addSeed(Seed_Table seed){
    ContentValues values = new ContentValues();
    values.put(COL_2, seed.get_seedName());
    values.put(COL_3, seed.get_seedType());
    values.put(COL_4, seed.get_amount());
    SQLiteDatabase db = getWritableDatabase();
    long rowInserted = db.insert(TABLE_NAME, null, values);
    if(rowInserted != -1) {
        insertToast();
    }
    else{
        noInsertToast();
    }
    db.close();
}

以下方法在预期活动的oncreate方法中调用。

public void AddData(){
    btnAddData.setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        int quantity =  Integer.parseInt(editSamount.getText().toString());

                        Seed_Table seed = new Seed_Table(
                                editSname.getText().toString(),
                                editStype.getText().toString(),
                                //editSamount.getText().toString()
                                quantity
                        );
                        myDb.addSeed(seed);
                        if(editSname.getText().length() != 0  &&
                                editStype.getText().length()  != 0 &&
                                editSamount.getText().length()  != 0){

                                    editSname.getText().clear();
                                    editStype.getText().clear();
                                    editSamount.getText().clear();
                        }
                        //Toast.makeText(SeedSave.this, "Data Inserted", Toast.LENGTH_LONG).show();
                    }
                    catch (Exception e){
                        e.printStackTrace();
                        //Toast.makeText(SeedSave.this, "Data not Inserted", Toast.LENGTH_LONG).show();
                    }
                }
            }
    );
}

目前我正在通过alertDialog.builder和字符串生成器查看数据。我想更改为列表视图,因为它可能看起来abit tider并且可能能够实际单击各个行来执行操作。以下是我如何查看数据,如果它有帮助: 在我希望使用的活动中,我在onCreate中调用此方法。

public void veiwAll(){
    btnViewAll.setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //res holds the data from the database
                   Cursor res = myDb.getAllData();

                    if(res.getCount() == 0){
                        // show message
                        showMessage("Error", "No Data in Database");
                        return;
                    }

                    StringBuffer myBuff = new StringBuffer();
                    while (res.moveToNext()){
                        myBuff.append("Id :"+ res.getString(0)+"\n");
                        myBuff.append("Name :"+ res.getString(1)+"\n");
                        myBuff.append("Type :"+ res.getString(2)+"\n");
                        myBuff.append("Amount :"+ res.getString(3)+"\n\n");
                    }
                    // show data
                    showMessage("Data",myBuff.toString());
                }
            }
    );
}

另见:

public void showMessage(String title,String message){
    AlertDialog.Builder myBuilder = new AlertDialog.Builder(this);
    myBuilder.setCancelable(true);
    myBuilder.setTitle(title);
    myBuilder.setMessage(message);
    myBuilder.show();
}

最终看起来像This here

这就是我相信的所有相关内容,以了解如何创建表格添加数据和检索数据。希望它有助于找到问题所在。

2 个答案:

答案 0 :(得分:0)

您应该在getAllData()中写下以下行而不是
SqliteDatabase db =this.getWrirtableDatabase()因为这里需要从数据库中读取数据: -

SqliteDatabase db=this.getReadableDatabase();

您也可以通过此链接获取正确的SQLite知识

Android sqlite tutorial

答案 1 :(得分:0)

您的结果集必须包含&#39; _id&#39;,这个&#39; _id&#39;游标适配器内部使用。光标适配器会发现&#39; _id&#39;这就是你的应用程序崩溃的原因

将您的SQL查询更改为

select ID AS _id,SNAME,STYPE FROM TABLE_NAME