问题
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
回答1:
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
}
}
回答2:
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.
回答3:
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;
}
回答4:
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
回答5:
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;
来源:https://stackoverflow.com/questions/21595300/getting-error-while-executing-getwritabledatabase-in-android