访问数据库SQLiteopenHelper方法时应用程序崩溃(nullpointerexception)

时间:2013-09-16 00:19:48

标签: java android sqlite listview android-listview

我的SQLite数据库还有另外一个问题。我在这个类的帮助下访问数据库,而且,在这里我创建数据库并预先填充它:

public class DatabaseHandler extends SQLiteOpenHelper {


    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "mydatabase";

    // Table names
    private static final String TABLE_DEVICE = "device";
    private static final String TABLE_ICON = "icon";

    // Column names of device table
    private static final String ID_DEVICE = "idDevice";
    private static final String UNIT_NUMBER = "unitNumber";
    private static final String DEVICE_ID = "deviceId";
    private static final String FK_ICON = "kdIcon";

    // Column names of icon table
    private static final String ID_ICON = "idIcon";
    private static final String CATEGORY = "category";
    private static final String ON = "iconOn";
    private static final String OFF = "iconOff";
    private static final String ON_COOLING = "onCooling";
    private static final String ON_HEATING = "onHeating";
    private static final String ICON_0 = "icon0";
    private static final String ICON_10 = "icon10";
    private static final String ICON_20 = "icon20";
    private static final String ICON_25 = "icon25";
    private static final String ICON_30 = "icon30";
    private static final String ICON_40 = "icon40";
    private static final String ICON_50 = "icon50";
    private static final String ICON_60 = "icon60";
    private static final String ICON_75 = "icon75";
    private static final String ICON_80 = "icon80";
    private static final String ICON_90 = "icon90";
    private static final String ICON_100 = "icon100";

    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);


    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createDeviceTable = "CREATE  TABLE " + TABLE_DEVICE + " ("
                + ID_DEVICE + " INTEGER PRIMARY KEY NOT NULL  UNIQUE , "
                + UNIT_NUMBER + " INTEGER NOT NULL  UNIQUE , " + DEVICE_ID
                + " INTEGER NOT NULL  UNIQUE , " + FK_ICON + " INTEGER)";

        String createIconTable = "CREATE  TABLE " + TABLE_ICON + " (" + ID_ICON
                + " INTEGER PRIMARY KEY NOT NULL  UNIQUE , " + CATEGORY
                + " INTEGER NOT NULL , " + ON + " TEXT, " + OFF + " TEXT, "
                + ON_COOLING + " TEXT, " + ON_HEATING + " TEXT, " + ICON_0
                + " TEXT, " + ICON_10 + " TEXT, " + ICON_20 + " TEXT, "
                + ICON_25 + " TEXT, " + ICON_30 + " TEXT, " + ICON_40
                + " TEXT, " + ICON_50 + " TEXT, " + ICON_60 + " TEXT, "
                + ICON_75 + " TEXT, " + ICON_80 + " TEXT, " + ICON_90
                + " TEXT, " + ICON_100 + " TEXT)";

        db.execSQL(createDeviceTable);
        db.execSQL(createIconTable);

        ContentValues values = new ContentValues();
        values.put(ID_ICON, 1);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v2");
        values.put(OFF, "lightbulb_100_v2");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 2);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v1");
        values.put(OFF, "lightbulb_max_v1");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 3);
        values.put(CATEGORY, 3);
        values.put(ON, "electric_outlet_on");
        values.put(OFF, "electric_outlet_off");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_DEVICE, 1);
        values.put(UNIT_NUMBER, 35100191);
        values.put(DEVICE_ID, 116);
        values.put(FK_ICON, 2);
        db.insert(TABLE_DEVICE, null, values);
        values.clear();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEVICE);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ICON);

        // Create tables again
        onCreate(db);

    }

    // It is used to show all availabe icons of category.
    public List<String> getAllIconsOfOldCategory(int oldCategory) {
        List<String> iconsList = new ArrayList<String>();

        String SqlSelectIconsQuery = "";
        // if (oldCategory == 3)
        SqlSelectIconsQuery = "SELECT " + ON + " FROM " + TABLE_ICON;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(SqlSelectIconsQuery, null);
        if (cursor.moveToFirst()) {
            do {
                iconsList.add(cursor.getString(0));
                Log.v("BAZA", cursor.getString(0));
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return iconsList;
        // return null;
    }

    public String getIcon(int deviceId, int unite_number, int status, int oldCategory) {
         SQLiteDatabase db = this.getReadableDatabase();
        // if (oldCategory == 3)
        String SqlFindIconId = "SELECT " + FK_ICON + " FROM " + TABLE_DEVICE
                + " WHERE " + UNIT_NUMBER + " = " + unite_number + " AND "
                + DEVICE_ID + " = " + deviceId;

        Cursor cursor = db.rawQuery(SqlFindIconId, null);
        if(cursor !=null){
            String icon;
            if(status == 0){
                icon = "SELECT "+ON+" FROM "+TABLE_ICON+ " WHERE "+ID_ICON +" = "+ cursor.getString(0);
            }else{
                icon = "SELECT "+OFF+" FROM "+TABLE_ICON+ " WHERE "+ID_ICON +" = "+ cursor.getString(0);
            }
            db.close();
            return db.rawQuery(SqlFindIconId, null).getString(0);
        }
        db.close();
        return null;
    }

}

现在,您可以看到有两种方法。首先,getAllIconsOfOldCategory(int oldCategory)和第二getIcon(int deviceId, int unite_number, int status, int oldCategory)。在应用程序中,我使用第一个metod,一切正常....但是当我尝试使用第二个方法时,应用程序在getIcon()方法开始执行并且应用程序被强制关闭之前抛出NullPointerException。

所以,下面我将提供类,我使用这个Databashandler类及其方法。这是,我们称之为classA.java。因此,classA(这扩展到另一个类)用于呈现listView和listView的每个单独行。 ([ImageView] [Text] [SwitchButton] - &gt;这是listView中的一行)。这里我有onCreate()方法:我认为这个方法没什么问题,因为它没有显示任何错误,当我按下imageView时它会起作用(你会在下面看到更多解释)。

private DatabaseHandler db;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    db = new DatabaseHandler(classA.this
            .getParent());

}

因此,在这个类中,有一些方法renderDevice()用于渲染listview中的所有行,并返回视图。我的目标是,检查数据库中是否有图像,显示此图像,如果没有,则显示预定义图像。但是,它不起作用......直到行,我称之为db.getIcon()方法。然后它显示错误。并且该方法甚至不开始执行。

ImageView device_status_image = (ImageView) lightView
                .findViewById(R.id.device_status_image);
        Settings settings = Settings.getInstance();  
        String icon = db.getIcon(light.id, settings.getLastPkAccessPoint(), status, light.oldCategory);

        if ( icon != null) {
            int resId = getResources().getIdentifier(icon, "drawable",
                    getPackageName());
            device_status_image.setImageResource(resId);
        } else
            device_status_image.setImageResource(R.drawable.normal_icon); 

        }

但是,此外,onClickListener上有device_status_image。这里有一切......所以,它打开了一个对话框。这意味着ClassA.this.getParent()很好并且有效。你可以看到,我在db.getAllIconsOfOldCategory()调用我设置新适配器的地方。

device_status_image.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            final Dialog dialog = new Dialog(ClassA.this
                    .getParent());
            dialog.setContentView(R.layout.list_view_icon);
            listView = (ListView) dialog.findViewById(R.id.list_view);

            IconAdapter adapter = new IconAdapter(inflater, light.id,
                    light.oldCategory, light.name, db
                            .getAllIconsOfOldCategory(light.oldCategory));    

            listView.setAdapter(adapter);
            dialog.show();

            Button bCancel = (Button) dialog.findViewById(R.id.bCancel);
            bCancel.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    dialog.dismiss();

                }
            });

        }
    });

所以,我尝试将String icon = db.getIcon(light.id, settings.getLastPkAccessPoint(), status, light.oldCategory);添加到OnClickListener中,只是为了检查方法是否执行(我通过调试检查)并且它工作正常,方法getIcon()已执行...但是,当我把它放回原来需要的地方。惊喜,惊讶,它不再起作用了..

而且,这是日志文件,如果它会帮助你。谢谢!这很长。

09-16 01:35:59.167: E/AndroidRuntime(28019): FATAL EXCEPTION: main
09-16 01:35:59.167: E/AndroidRuntime(28019): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mysite.android/com.mysite.mobile.LightsActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mysite.android/com.mysite.mobile.classA}: java.lang.NullPointerException
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2194)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.startActivityNow(ActivityThread.java:1991)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:135)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:347)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:703)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost.setCurrentTab(TabHost.java:350)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:154)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:540)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.view.View.performClick(View.java:3549)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.view.View$PerformClick.run(View.java:14393)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.os.Handler.handleCallback(Handler.java:605)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.os.Handler.dispatchMessage(Handler.java:92)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.os.Looper.loop(Looper.java:154)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.main(ActivityThread.java:4945)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at java.lang.reflect.Method.invokeNative(Native Method)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at java.lang.reflect.Method.invoke(Method.java:511)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at dalvik.system.NativeStart.main(Native Method)
09-16 01:35:59.167: E/AndroidRuntime(28019): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mysite.android/com.mysite.mobile.classA}: java.lang.NullPointerException
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2194)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.startActivityNow(ActivityThread.java:1991)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:135)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:347)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:703)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost.setCurrentTab(TabHost.java:350)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.widget.TabHost.addTab(TabHost.java:240)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.LightsActivity.changeDeviceTabs(LightsActivity.java:34)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.LightsActivity.onCreate(LightsActivity.java:19)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.Activity.performCreate(Activity.java:4531)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
09-16 01:35:59.167: E/AndroidRuntime(28019):    ... 18 more
09-16 01:35:59.167: E/AndroidRuntime(28019): Caused by: java.lang.NullPointerException
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.classA.renderDevice(classA.java:89)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.MyViewDeviceActivity.renderDevices(MyViewDeviceActivity.java:58)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.MyViewDeviceActivity.onCreate(MyViewDeviceActivity.java:30)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at com.mysite.mobile.classA.onCreate(classA.java:38)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.Activity.performCreate(Activity.java:4531)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
09-16 01:35:59.167: E/AndroidRuntime(28019):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
09-16 01:35:59.167: E/AndroidRuntime(28019):    ... 29 more

1 个答案:

答案 0 :(得分:0)

从我在日志中可以看出,你应该检查'light'并且Settings.getInstance()不是null。它可以在你的onClickListener而不是那个方法中工作的原因可能是因为它们在你点击图像之前在某处被实例化,而不是在调用renderDevice()之前实例化。

尝试在renderDevice()方法中执行类似的操作:

ImageView device_status_image = (ImageView) lightView
            .findViewById(R.id.device_status_image);
    Settings settings = Settings.getInstance();

    if( light == null)
    {
       /* instantiate your light variable */
    }

    if ( settings == null )
    {
      /* write the necessary code to make sure your singleton gets created */
    }  
    String icon = db.getIcon(light.id, settings.getLastPkAccessPoint(), status, light.oldCategory);

    if ( icon != null) {
        int resId = getResources().getIdentifier(icon, "drawable",
                getPackageName());
        device_status_image.setImageResource(resId);
    } else
        device_status_image.setImageResource(R.drawable.normal_icon); 

    }