mercredi 1 juillet 2015

Null pointer exception whilst adding to the DB

I'm developing a simple bird-watching log app for one of my classes at college and I seem to not be able to spot what the heck is going wrong, so after spending a few days banging my head against the wall, I suppose it'd make more sense to just ask for someone with a fresh pair of eyes to have a look.

The app is really simple - I have two activities, one with a ListView, that gets populated by the DB (MainActivity) and another, that takes the arguments to create a new entry (AddActivity). Besides these I have a DBHelper (MySQLiteHelper) to handle my DB calls, a simple class to describe how my object should look like (Sighting), a DataSource class (SightingDataSource) to handle facilitate the calls to the helper and a bunch of non-relevant resources (layouts, etc.) The AddActivity blows up with null pointer exceptions whilst calling the addSighting method. It also for whatever reason doesn't like the int typecast of the bCount field, so for testing purposes I've set a static int, just whilst I figure out the exception portion of my problem.

Here's my source: AddActivity:

package com.vladislavtachev.cscb763;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AddActivity extends ListActivity {

    public SightingsDataSource datasource;

    private EditText locFld = null;
    private EditText bNameFld = null;
    private EditText bCountFld = null;
    private Button addSightBtn = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);
        locFld = (EditText) findViewById(R.id.locFld);
        bNameFld = (EditText) findViewById(R.id.bNameFld);
        bCountFld = (EditText) findViewById(R.id.bCountFld);
        setContentView(R.layout.activity_add);
        addSightBtn = (Button) findViewById(R.id.addSightBtn);
        addSightBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addSight(v);
            }
        });


    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) { return true; }
        return super.onOptionsItemSelected(item);
    }


    public void addSight(View view){
        long time = System.currentTimeMillis()/1000L;
                datasource.addSighting(locFld.getText().toString(),
                        time,
                        bNameFld.getText().toString(),3
//                        Integer.parseInt(bCountFld.getText().toString())
                );
//        datasource.addSighting(sighting);
        setContentView(R.layout.activity_main);

    }
}

SightingDataSource

package com.vladislavtachev.cscb763;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class SightingsDataSource {

    //DB info
    private SQLiteDatabase database;
    private MySQLiteHelper dbHelper;
    private String[] allColumns = { MySQLiteHelper.COL_ID, MySQLiteHelper.COL_LOCATION,
            MySQLiteHelper.COL_TIME, MySQLiteHelper.COL_BNAME, MySQLiteHelper.COL_BCOUNT };

    public SightingsDataSource(Context context){
        dbHelper = new MySQLiteHelper(context);
    }

    public void open(){
        database = dbHelper.getWritableDatabase();
    }

    public void close(){ dbHelper.close(); }

    public void addSighting(String l, long time, String bName, int bCount){
        ContentValues values = new ContentValues();
        values.put(MySQLiteHelper.COL_LOCATION, l);
        values.put(MySQLiteHelper.COL_TIME, time);
        values.put(MySQLiteHelper.COL_BNAME, bName);
        values.put(MySQLiteHelper.COL_BCOUNT, bCount);
        long insertId = database.insert(MySQLiteHelper.TABLE_SIGHTINGS, null, values);
        Cursor cursor = database.query(MySQLiteHelper.TABLE_SIGHTINGS, allColumns, MySQLiteHelper.COL_ID + " = " + insertId, null, null, null, null);
        cursor.moveToFirst();
        Sighting newSighting = cursorToSighting(cursor);
        cursor.close();
    }

    private Sighting cursorToSighting(Cursor cursor){
        Sighting sighting = new Sighting();
        sighting.setId(cursor.getLong(0));
        sighting.setLocation(cursor.getString(1));
        sighting.setTime(cursor.getLong(2));
        sighting.setbName(cursor.getString(3));
        sighting.setbCount(cursor.getInt(4));
        return sighting;
    }

    public List<Sighting> getAllSightings(){
        List<Sighting> sightings = new ArrayList<Sighting>();
        Cursor cursor = database.query(MySQLiteHelper.TABLE_SIGHTINGS, allColumns, null, null, null, null, null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            Sighting sighting = cursorToSighting(cursor);
            sightings.add(sighting);
            cursor.moveToNext();
        }
        cursor.close();
        return sightings;
    }
}

MySQLiteHelper

package com.vladislavtachev.cscb763;

import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.content.Context;

public class MySQLiteHelper extends SQLiteOpenHelper{

    public final static String DB_NAME = "sightings.db";
    public final static int DB_VER = 1;
    public final static String TABLE_SIGHTINGS = "sightings";
    public final static String COL_ID = "_id";
    public final static String COL_LOCATION = "_loc";
    public final static String COL_TIME = "_time";
    public final static String COL_BNAME = "_bname";
    public final static String COL_BCOUNT = "_bcount";

    private final static String DB_CREATE = "create table if not exists"
            + TABLE_SIGHTINGS + "("
            + COL_ID + " integer primary key autoincrement, "
            + COL_LOCATION + " text not null, "
            + COL_TIME + " integer not null, "
            + COL_BNAME + " text not null, "
            + COL_BCOUNT + " integer not null);";

    public MySQLiteHelper(Context context){
        super(context, DB_NAME, null, DB_VER);
    }

    @Override
    public void onCreate(SQLiteDatabase database){
        database.execSQL(DB_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVer, int newVer){
        database.execSQL("DROP TABLE IF EXISTS " + TABLE_SIGHTINGS);
        onCreate(database);
    }

}

activity_add.xml layout

<RelativeLayout xmlns:android="http://ift.tt/nIICcg"
    xmlns:tools="http://ift.tt/LrGmb4"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.vladislavtachev.cscb763.AddActivity"
    style="@android:style/Theme.Material">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/lblBName"
        android:id="@+id/lblBName"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/bNameFld"
        android:layout_below="@+id/lblBName"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/lblBCount"
        android:id="@+id/lblBCount"
        android:layout_alignBottom="@+id/bCountFld"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="10"
        android:id="@+id/bCountFld"
        android:layout_below="@+id/bNameFld"
        android:layout_alignRight="@+id/bNameFld"
        android:layout_alignEnd="@+id/bNameFld"
        android:layout_toEndOf="@+id/lblBCount"
        android:layout_toRightOf="@+id/lblBCount" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/lblLocation"
        android:id="@+id/lblLocation"
        android:layout_alignBottom="@+id/locFld"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/locFld"
        android:layout_below="@+id/bCountFld"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_toEndOf="@+id/lblLocation"
        android:layout_toRightOf="@+id/lblLocation" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/addSightBtn"
        android:id="@+id/addSightBtn"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"/>

    <ListView
        android:layout_width="10px"
        android:layout_height="10px"
        android:id="@android:id/list"
        android:layout_alignParentBottom="true"
        android:layout_alignRight="@+id/locFld"
        android:layout_alignEnd="@+id/locFld" />
</RelativeLayout>

Error stack

07-01 18:08:49.131    2384-2384/com.vladislavtachev.cscb763 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.vladislavtachev.cscb763, PID: 2384
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.vladislavtachev.cscb763.SightingsDataSource.addSighting(java.lang.String, long, java.lang.String, int)' on a null object reference
            at com.vladislavtachev.cscb763.AddActivity.addSight(AddActivity.java:75)
            at com.vladislavtachev.cscb763.AddActivity$1.onClick(AddActivity.java:38)
            at android.view.View.performClick(View.java:4780)
            at android.view.View$PerformClick.run(View.java:19866)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

All help is appreciated!

Cheers, V./

Aucun commentaire:

Enregistrer un commentaire