Android 未创建nullpointerexception和数据库
我的头撞到桌子上了。我就是想不出来。我所要做的就是在创建活动时用SQLite数据库中的项目填充listview 也许我错过了一些小的东西,我不知道在这一点上,我超越了沮丧。我知道数据库没有被创建,因为它不在文件资源管理器中 下面是DatabaseHandler.java:Android 未创建nullpointerexception和数据库,android,sqlite,listview,simplecursoradapter,Android,Sqlite,Listview,Simplecursoradapter,我的头撞到桌子上了。我就是想不出来。我所要做的就是在创建活动时用SQLite数据库中的项目填充listview 也许我错过了一些小的东西,我不知道在这一点上,我超越了沮丧。我知道数据库没有被创建,因为它不在文件资源管理器中 下面是DatabaseHandler.java: package com.dd.gfit; import android.content.Context; import android.database.Cursor; import android.database.sql
package com.dd.gfit;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHandler extends SQLiteOpenHelper {
private SQLiteDatabase db;
// database strings
public static final String DATABASE_NAME = "gfit.db";
public static final int DATABASE_VERSION = 1;
// table strings
public static final String TABLE_ROUTINES = "routines";
// key strings
public static final String KEY_ROUTINES_ID = "id";
public static final String KEY_ROUTINES_NAME = "name";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// create routines table
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_ROUTINES + " ("
+ KEY_ROUTINES_ID + " INTEGER PRIMARY KEY AUTO_INCREMENT,"
+ KEY_ROUTINES_NAME + " VARCHAR"
+ ")");
// insert test data into routines table
db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 1')");
db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 2')");
db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 3')");
db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 4')");
db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 5')");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// do database upgrades here
}
public Cursor fetchRoutines() {
Cursor cursor = db.query(TABLE_ROUTINES, new String[] {KEY_ROUTINES_ID, KEY_ROUTINES_NAME}, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
}
下面是RoutinesActivity.java:
package com.dd.gfit;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class RoutinesActivity extends Activity {
private DatabaseHandler db = new DatabaseHandler(this);
private Cursor cursor = db.fetchRoutines();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routines);
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
// open the database and show the routines
db.getWritableDatabase();
displayRoutines();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_routines, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
private void displayRoutines() {
ListAdapter adapter = new SimpleCursorAdapter(
this,
R.layout.listitem_routine, cursor,
new String[] { db.KEY_ROUTINES_NAME },
new int[] { R.id.listitem_routine_name });
ListView routineList = (ListView)findViewById(R.id.list_routines);
routineList.setAdapter(adapter);
}
}
以下是activity_routines.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RoutinesActivity" >
<ListView
android:id="@+id/list_routines"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp" >
</ListView>
</RelativeLayout>
以下是listitem_routine.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical" >
<TextView
android:id="@+id/listitem_routine_name"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/lorem_routine_item"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/button_routine_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_edit"
android:contentDescription="@string/ic_action_edit" />
<ImageView
android:id="@+id/button_routine_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_delete"
android:contentDescription="@string/ic_action_delete" />
</LinearLayout>
这里怎么了?此外,一旦我开始工作,每个listview项中都有按钮,您可以通过listitem_routine.xml看到这些按钮。我想以某种方式将KEY_ROUTINES_ID传递到按钮中,以便可以动态编辑每个项目。有没有一个教程我可以使用任何人都知道或可能只是一个片段
编辑:
以下是日志:
12-24 02:52:24.429: D/dalvikvm(783): GC_FOR_ALLOC freed 49K, 7% free 2564K/2732K, paused 68ms, total 69ms
12-24 02:52:24.449: I/dalvikvm-heap(783): Grow heap (frag case) to 3.616MB for 1048592-byte allocation
12-24 02:52:24.559: D/dalvikvm(783): GC_FOR_ALLOC freed 2K, 5% free 3585K/3760K, paused 110ms, total 110ms
12-24 02:52:24.659: D/dalvikvm(783): GC_CONCURRENT freed <1K, 5% free 3585K/3760K, paused 5ms+3ms, total 102ms
12-24 02:52:24.839: D/dalvikvm(783): GC_FOR_ALLOC freed <1K, 5% free 3585K/3760K, paused 51ms, total 51ms
12-24 02:52:24.869: I/dalvikvm-heap(783): Grow heap (frag case) to 5.863MB for 2359312-byte allocation
12-24 02:52:24.989: D/dalvikvm(783): GC_CONCURRENT freed 0K, 3% free 5889K/6068K, paused 24ms+33ms, total 115ms
12-24 02:52:25.319: D/gralloc_goldfish(783): Emulator without GPU emulation detected.
12-24 02:52:31.950: E/Trace(827): error opening trace file: No such file or directory (2)
12-24 02:52:32.660: D/dalvikvm(827): GC_FOR_ALLOC freed 52K, 7% free 2564K/2736K, paused 25ms, total 28ms
12-24 02:52:32.670: I/dalvikvm-heap(827): Grow heap (frag case) to 3.616MB for 1048592-byte allocation
12-24 02:52:32.710: D/dalvikvm(827): GC_FOR_ALLOC freed 2K, 5% free 3585K/3764K, paused 40ms, total 40ms
12-24 02:52:32.760: D/dalvikvm(827): GC_CONCURRENT freed <1K, 5% free 3585K/3764K, paused 5ms+3ms, total 50ms
12-24 02:52:32.840: D/dalvikvm(827): GC_FOR_ALLOC freed <1K, 5% free 3585K/3764K, paused 19ms, total 19ms
12-24 02:52:32.860: I/dalvikvm-heap(827): Grow heap (frag case) to 5.863MB for 2359312-byte allocation
12-24 02:52:33.000: D/dalvikvm(827): GC_CONCURRENT freed 0K, 4% free 5889K/6072K, paused 77ms+13ms, total 140ms
12-24 02:52:33.250: D/gralloc_goldfish(827): Emulator without GPU emulation detected.
12-24 02:52:36.120: D/AndroidRuntime(827): Shutting down VM
12-24 02:52:36.140: W/dalvikvm(827): threadid=1: thread exiting with uncaught exception (group=0x40a70930)
12-24 02:52:36.190: E/AndroidRuntime(827): FATAL EXCEPTION: main
12-24 02:52:36.190: E/AndroidRuntime(827): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.dd.gfit/com.dd.gfit.RoutinesActivity}: java.lang.NullPointerException
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.access$600(ActivityThread.java:141)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.os.Handler.dispatchMessage(Handler.java:99)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.os.Looper.loop(Looper.java:137)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.main(ActivityThread.java:5039)
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.reflect.Method.invokeNative(Native Method)
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.reflect.Method.invoke(Method.java:511)
12-24 02:52:36.190: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-24 02:52:36.190: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-24 02:52:36.190: E/AndroidRuntime(827): at dalvik.system.NativeStart.main(Native Method)
12-24 02:52:36.190: E/AndroidRuntime(827): Caused by: java.lang.NullPointerException
12-24 02:52:36.190: E/AndroidRuntime(827): at com.dd.gfit.DatabaseHandler.fetchRoutines(DatabaseHandler.java:51)
12-24 02:52:36.190: E/AndroidRuntime(827): at com.dd.gfit.RoutinesActivity.<init>(RoutinesActivity.java:17)
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.Class.newInstanceImpl(Native Method)
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.Class.newInstance(Class.java:1319)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
12-24 02:52:36.190: E/AndroidRuntime(827): ... 11 more
12-24 02:52:24.429:D/dalvikvm(783):全部释放49K,7%释放2564K/2732K,暂停68ms,总计69ms
12-24 02:52:24.449:I/dalvikvm堆(783):为1048592字节分配将堆(frag案例)增长到3.616MB
12-24 02:52:24.559:D/dalvikvm(783):释放2K,5%释放3585K/3760K,暂停110毫秒,总计110毫秒
12-24 02:52:24.659:D/dalvikvm(783):GC_CONCURRENT freed以下行中的这个
关键字是导致崩溃的原因。
在创建对象之前,您正在使用“this”关键字
private DatabaseHandler db = new DatabaseHandler(this);
执行以下操作
private DatabaseHandler db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routines);
db = new DatabaseHandler(this);
}
同时将以下行移到onCreate()中
以下行中的这个
关键字是导致崩溃的原因。
在创建对象之前,您正在使用“this”关键字
private DatabaseHandler db = new DatabaseHandler(this);
执行以下操作
private DatabaseHandler db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routines);
db = new DatabaseHandler(this);
}
同时将以下行移到onCreate()中
您无法调用它,因为它尚未调用onCreate()
<代码>db.fetchRoutines()代码>将从数据库中调用某些内容。但您已经创建了db对象。”无法使用此“”,因为对象尚未构造
private DatabaseHandler db = null;
private Cursor cursor = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routines);
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
// open the database and show the routines
db = new DatabaseHandler(this);
db.getWritableDatabase();
cursor = db.fetchRoutines();
displayRoutines();
}
这种方法
db = new DatabaseHandler(this);
是创建对象的位置
db.getWritableDatabase();
是您获取db的地方,您只能在此行之后使用db操作
您无法调用它,因为它尚未调用onCreate()
<代码>db.fetchRoutines()代码>将从数据库中调用某些内容。但您已经创建了db对象。”无法使用此“”,因为对象尚未构造
private DatabaseHandler db = null;
private Cursor cursor = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routines);
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
// open the database and show the routines
db = new DatabaseHandler(this);
db.getWritableDatabase();
cursor = db.fetchRoutines();
displayRoutines();
}
这种方法
db = new DatabaseHandler(this);
是创建对象的位置
db.getWritableDatabase();
是获取db的地方,只能在此行之后使用db操作。在DatabaseHandler
中,从不分配db
的值。因此,当您在fetchRoutines()
中调用db.query()
时,它会崩溃
您需要设置db
成员变量,以便以后使用。将以下行添加到DatabaseHandler.onCreate()的末尾:
在DatabaseHandler
中,您从不分配db
的值。因此,当您在fetchRoutines()
中调用db.query()
时,它会崩溃
您需要设置db
成员变量,以便以后使用。将以下行添加到DatabaseHandler.onCreate()的末尾:
你忘了上传最重要的信息,那就是日志。现在就用日志更新我的OP。@scarhand:帮你自己一个忙……在你的活动中
你把你的数据库处理程序命名为db
,但是db
在代码的其他地方被用来表示实际的数据库。将你的DatabaseHandler
实例重命名为dbh
或除db
以外的任何东西。你忘记上载最重要的信息,那就是日志。现在用日志更新我的OP。@scarhand:帮你自己一个忙……在你的活动中
你将你的DatabaseHandler
命名为db
,但是db
在代码中的其他地方用于表示实际的数据库。将您的DatabaseHandler
实例重命名为dbh
或除db
以外的任何其他名称。如何正确调用oncreate来创建DatabaseHandler?这一定是问题所在。它没有调用oncreate,因此没有创建数据库。有没有什么方法可以在不进行oncreate()上面的null声明的情况下执行此操作?或者我必须这样做,以便在类的其他函数中使用它吗?另一种方法是将对其他函数的引用作为参数传递,但将它们设置为null声明似乎更容易。如何正确地为DatabaseHandler调用oncreate?这一定是问题所在。它没有调用oncreate,因此没有创建数据库。有没有什么方法可以在不进行oncreate()上面的null声明的情况下执行此操作?或者我必须这样做,以便在类的其他函数中使用它吗?另一种方法是将对其他函数的引用作为参数传递,但是将它们设置为null声明似乎更容易。