Question

I have created one class for database and multiple classes for tables and multiple activity classess everything works fine when I use the database class instance in activity class but at the same time when I use the database class instance in table class and run the application as soon as the control goes to getwritabledatabase I am getting exception and application is exited, below is the code for all 3 classes.

Database class.

public class Database extends SQLiteOpenHelper{

    private static  String dbname="Manager";
    private static int dbversion=2;
    SQLiteDatabase db;

    public Database(Context context) {

        super(context, dbname, null, dbversion);
        // TODO Auto-generated constructor stub
        db=this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        StockTable st=new StockTable();
        db.execSQL(st.stocktable);
        }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

Activity class

public class stockmanager extends Activity{

    String getentry=null;
    Database d=new Database(this);
    StockTable st=new StockTable();


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stockmanager);

    final Button AddStock=(Button) findViewById(R.id.button1);
        final EditText entry=(EditText) findViewById(R.id.editText1);
        final Button BroDetail=(Button) findViewById(R.id.button2);

        AddStock.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                getentry=entry.getText().toString();
                d.db.insert(st.tablename, null,st.insert());


            }
        });
                }
}

Table Class

    public class StockTable {

    Context c1;
    Database d1=new Database(c1);
    final String tablename="StockTable";
    private String column1="Stock_ID";
    private String column2="StockName";


    final String stocktable = "CREATE TABLE " + tablename + 
                " (" + column1+ " INTEGER PRIMARY KEY , " + column2 + " TEXT) ";

    public ContentValues insert(){

String select="Select StockID from Stocktable";

d.db.execsql(select);
        ContentValues cvi=new ContentValues();
        for(int i=0;i<=sm.getentry.length();i++)
        {
            cvi.put(column1, 1);
            cvi.put(column2,sm.getentry);
                        }

        return cvi;
    }

    public void delete(){


    }

First when control goes to getwritabledatabase of database class from activity class then it is executing but after when control from stock table class goes to database class and executes getwritabledatabase exception is occurred, Unfortunately I am unable to paste the exceptions here.

Can anyone please help me to solve this ?

Logcat

02-07 10:06:09.624: D/libEGL(10756): loaded /system/lib/egl/libEGL_genymotion.so
02-07 10:06:09.628: D/(10756): HostConnection::get() New Host Connection established 0xb87f5e00, tid 10756
02-07 10:06:09.720: D/libEGL(10756): loaded /system/lib/egl/libGLESv1_CM_genymotion.so
02-07 10:06:09.748: D/libEGL(10756): loaded /system/lib/egl/libGLESv2_genymotion.so
02-07 10:06:10.024: W/EGL_genymotion(10756): eglSurfaceAttrib not implemented
02-07 10:06:10.044: E/OpenGLRenderer(10756): Getting MAX_TEXTURE_SIZE from GradienCache
02-07 10:06:10.196: E/OpenGLRenderer(10756): Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
02-07 10:06:10.212: D/OpenGLRenderer(10756): Enabling debug mode 0
02-07 10:07:17.328: W/EGL_genymotion(10756): eglSurfaceAttrib not implemented
02-07 10:07:19.820: I/Choreographer(10756): Skipped 36 frames!  The application may be doing too much work on its main thread.
02-07 10:07:22.556: W/EGL_genymotion(10756): eglSurfaceAttrib not implemented
02-07 10:07:22.788: I/Choreographer(10756): Skipped 44 frames!  The application may be doing too much work on its main thread.
02-07 10:07:28.064: D/dalvikvm(10756): GC_FOR_ALLOC freed 105K, 1% free 16944K/17072K, paused 37ms, total 40ms
02-07 10:07:30.524: I/System.out(10756): asdfdw
02-07 10:07:30.576: D/AndroidRuntime(10756): Shutting down VM
02-07 10:07:30.612: W/dalvikvm(10756): threadid=1: thread exiting with uncaught exception (group=0xa4b6e648)
02-07 10:07:30.652: E/AndroidRuntime(10756): FATAL EXCEPTION: main
02-07 10:07:30.652: E/AndroidRuntime(10756): android.database.sqlite.SQLiteException: unknown error (code 0): Queries can be performed using SQLiteDatabase query or rawQuery methods only.
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:734)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1603)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at com.example.portfoliomanager.StockTable.insert(StockTable.java:43)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at com.example.portfoliomanager.stockmanager$1.onClick(stockmanager.java:36)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.view.View.performClick(View.java:4240)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.view.View$PerformClick.run(View.java:17721)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.os.Handler.handleCallback(Handler.java:730)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.os.Handler.dispatchMessage(Handler.java:92)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.os.Looper.loop(Looper.java:137)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at android.app.ActivityThread.main(ActivityThread.java:5103)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at java.lang.reflect.Method.invokeNative(Native Method)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at java.lang.reflect.Method.invoke(Method.java:525)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-07 10:07:30.652: E/AndroidRuntime(10756):    at dalvik.system.NativeStart.main(Native Method)
02-07 10:07:34.288: I/Process(10756): Sending signal. PID: 10756 SIG: 9
02-07 10:07:36.624: D/libEGL(10871): loaded /system/lib/egl/libEGL_genymotion.so
02-07 10:07:36.644: D/(10871): HostConnection::get() New Host Connection established 0xb87f5e70, tid 10871
02-07 10:07:36.784: D/libEGL(10871): loaded /system/lib/egl/libGLESv1_CM_genymotion.so
02-07 10:07:36.784: D/libEGL(10871): loaded /system/lib/egl/libGLESv2_genymotion.so
02-07 10:07:37.104: W/EGL_genymotion(10871): eglSurfaceAttrib not implemented
02-07 10:07:37.108: E/OpenGLRenderer(10871): Getting MAX_TEXTURE_SIZE from GradienCache
02-07 10:07:37.132: E/OpenGLRenderer(10871): Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
02-07 10:07:37.132: D/OpenGLRenderer(10871): Enabling debug mode 0
Was it helpful?

Solution

Error is because you trying to access database with null context. So you need to initialize c1 before passing to Database constructor.

I just Edit your StockTable.java try this

import android.content.ContentValues;
import android.content.Context;

public class StockTable {

    Context c1;
    Database d1;
    final String tablename = "StockTable";
    private String column1 = "Stock_ID";
    private String column2 = "StockName";

    final String stocktable = "CREATE TABLE " + tablename + " (" + column1 + " INTEGER PRIMARY KEY , " + column2 + " TEXT) ";


    public StockTable(Context mContext){
        c1= mContext;
        d1= new Database(c1);
    }
    public ContentValues insert() {


        ContentValues cvi = new ContentValues();
        for (int i = 0; i <= sm.getentry.length(); i++) {
            cvi.put(column1, 1);
            cvi.put(column2, sm.getentry);
        }

        return cvi;
    }

    public void delete() {

    }
}

How to Use?

public class stockmanager extends Activity {

    String getentry = null;
    Database d;
    StockTable st;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stockmanager);

        d = new Database(this.getApplicationContext());
        st = new StockTable(this.getApplicationContext());

        final Button AddStock = (Button) findViewById(R.id.button1);
        final EditText entry = (EditText) findViewById(R.id.editText1);
        final Button BroDetail = (Button) findViewById(R.id.button2);

        AddStock.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                getentry = entry.getText().toString();
                d.db.insert(st.tablename, null, st.insert());

            }
        });
    }
}

UPDATE YOUR Database Class

public class Database extends SQLiteOpenHelper {

    private static String dbname = "Manager";
    private static int dbversion = 2;
    SQLiteDatabase db;
    private Context mContext;

    public Database(Context context) {

        super(context, dbname, null, dbversion);
        // TODO Auto-generated constructor stub
        mContext = context;
        db = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        StockTable st = new StockTable(mContext);
        db.execSQL(st.stocktable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

OTHER TIPS

You should replace this

String select="Select StockID from Stocktable";

With

String select="Select Stock_ID from Stocktable";

And also initialized your Context C1. Create Constructor that passed current Context into StockTable like:

public StockTable(Context cxnt){
this.c1=cxnt;
d1=new Database(c1);
 }

And add this

 StockTable st=new StockTable(this);

into your stockmanager activity.

StockID & Stock_ID are two different column name.

While creating table you are using Stock_ID as column and while firing select query you are using StockID as column, that's your mistake. Your query should be

String select="Select Stock_ID from Stocktable";

And also initialized your Context C1. Create Constructor that passed current Context into StockTable like:

public StockTable(Context cxnt){
this.c1=cxnt;
 }

Whenever you are working with the database and helper,

Database database = new Database(this); 

You cannot use the class instance as Context until onCreate(). Defer your database and db initialization to onCreate() or later.

Refer these also, to understand it better:

SQlite Database: Unable to find context
nullPointerException for SQLiteOpenHelper.getWritableDatabase(), Android

When you instantiate StockTable, these two lines are a problem:

Context c1;
Database d1=new Database(c1);

c1 is not initialized.. there is no context in which to create the database. Pass in a valid context to your constructor, or use a "set" method, then instantiate your database for use. Like this:

public StockTable(Context context) {
 c1 = context;
 d1=new Database(c1);
}

And I would replace:

String select="Select StockID from Stocktable";

with:

String select="Select "+  column1 + " from " + tablename;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top