我想在我的应用中使用 External database
。在我的应用程序中有4 fragment
,并在数据库中显示任何一个表的数据库(数据库有4个表)。但是当开始运行应用程序时,请显示以下错误:
03-06 16:59:46.350 9654-9654/com.tellfa.dastanak E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tellfa.dastanak, PID: 9654
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
at com.tellfa.dastanak.Database.DataBase.getCat1_Datas2(DataBase.java:156)
at com.tellfa.dastanak.Fragments.Home_Frag.refreshData(Home_Frag.java:58)
at com.tellfa.dastanak.Fragments.Home_Frag.onCreateView(Home_Frag.java:49)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1474)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:610)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:677)
at android.view.View.measure(View.java:17496)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:940)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2636)
at android.view.View.measure(View.java:17496)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2031)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1193)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1400)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1078)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5875)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
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:5349)
at java.lang.reflect.Met
数据库代码:
public class DataBase extends SQLiteOpenHelper {
private static String DB_PATH = "";
private static String DB_NAME = "Dastansara";
private static int DB_VERSION = 1;
private SQLiteDatabase sqLiteDatabase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
*
* @param context
*/
public DataBase(Context context) {
super(context, DB_NAME, null, DB_VERSION);
if (android.os.Build.VERSION.SDK_INT >= 17) {
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
this.myContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
/**
* Creates a empty database on the system and rewrites it with your own database.
*/
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database alerdy exist
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
*
* @return true if it exists, false if it doesn't
*/
public boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPATH = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPATH, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
/// database does't exist yet
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Open DataBase
*
* @throws SQLException
*/
public void openDataBase() throws SQLException {
String myPATH = DB_PATH + DB_NAME;
sqLiteDatabase = SQLiteDatabase.openDatabase(myPATH, null, SQLiteDatabase.OPEN_READONLY);
}
/**
* Close DataBase
*/
public void closeDataBase() {
sqLiteDatabase.close();
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
*/
public void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String myPath = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(myPath);
byte[] buffer = new byte[1024];
int length;
//transfer bytes from the inputfile to the outputfile
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
@Override
public synchronized void close() {
if (sqLiteDatabase != null) {
sqLiteDatabase.close();
}
super.close();
}
public Cursor getCat1_Datas2() {
try {
String query = "SELECT * FROM tbl_Book WHERE Cat_ID = 1";
Cursor cursor = sqLiteDatabase.rawQuery(query, null);
if (cursor != null) {
cursor.moveToNext();
}
return cursor;
} catch (SQLException e) {
Log.e("Data Adapter", "getTestData >>" + e.toString());
throw e;
}
}
DataProvider代码:
public class DataProvider {
int _id, _catID, _fav;
String _title, _description;
byte[] _image;
public DataProvider(int key_id, int key_catID, int key_fav, String key_title, String key_description, byte[] key_image) {
this._id = key_id;
this._catID = key_catID;
this._fav = key_fav;
this._title = key_title;
this._description = key_description;
this._image = key_image;
}
/// Empty Constructor
public DataProvider(){
}
public DataProvider(int key_id, String key_title){
this._id = key_id;
this._title = key_title;
}
public byte[] getKey_image() {
return _image;
}
public void setKey_image(byte[] key_image) {
_image = key_image;
}
public String getKey_description() {
return _description;
}
public void setKey_description(String key_description) {
_description = key_description;
}
public String getKey_title() {
return _title;
}
public void setKey_title(String key_title) {
_title = key_title;
}
public int getKey_fav() {
return _fav;
}
public void setKey_fav(int key_fav) {
_fav = key_fav;
}
public int getKey_catID() {
return _catID;
}
public void setKey_catID(int key_catID) {
_catID = key_catID;
}
public int getKey_id() {
return _id;
}
public void setKey_id(int key_id) {
_id = key_id;
}
}
片段代码:
public class Home_Frag extends Fragment {
DataProvider dataProvider;
DataBase dataBase;
SQLiteDatabase sqLiteDatabase;
Cursor cursor;
ListView listView;
Cat1_frag_adapter cat1FragAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.frag_home,
container, false);
refreshData();
return rootView;
}
public void refreshData(){
dataBase = new DataBase(getActivity());
sqLiteDatabase = dataBase.getReadableDatabase();
cursor = dataBase.getCat1_Datas2();
listView = (ListView) getActivity().findViewById(R.id.list);
cat1FragAdapter = new Cat1_frag_adapter(getActivity(), R.layout.list_card_layout);
listView.setAdapter(cat1FragAdapter);
if (cursor.moveToFirst()){
do {
int id, catID, fav;
String title, desvription;
byte[] image;
id = cursor.getInt(0);
title = cursor.getString(2);
dataProvider = new DataProvider(id, title);
cat1FragAdapter.add(dataProvider);
} while (cursor.moveToNext());
}
}
}
如何解决这个问题? tnx all< 3
答案 0 :(得分:1)
你的问题在这里:
public Cursor getCat1_Datas2() {
try {
String query = "SELECT * FROM tbl_Book WHERE Cat_ID = 1";
Cursor cursor = sqLiteDatabase.rawQuery(query, null);
if (cursor != null) {
cursor.moveToNext();
}
return cursor;
} catch (SQLException e) {
Log.e("Data Adapter", "getTestData >>" + e.toString());
throw e;
}
}
正在提供NullPointerException
,因为如http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
sql String:SQL查询。不得终止SQL字符串
selectionArgs字符串:您可以包括?在查询中的where子句中,它将被selectionArgs中的值替换。这些值将绑定为字符串。
所以你需要做的就是将你的代码更改为:
public Cursor getCat1_Datas2() {
try {
String query = "SELECT * FROM tbl_Book WHERE Cat_ID = ?";
Cursor cursor = sqLiteDatabase.rawQuery(query, new String[] {"1"});
if (cursor != null) {
cursor.moveToNext();
}
return cursor;
} catch (SQLException e) {
Log.e("Data Adapter", "getTestData >>" + e.toString());
throw e;
}
}
在您onCreateView
的{{1}}方法中,您有这个:
Fragment
像这样修改你的方法:
dataBase = new DataBase(getActivity());
sqLiteDatabase = dataBase.getReadableDatabase();
cursor = dataBase.getCat1_Datas2();
然后在public Cursor getCat1_Datas2(SQLiteDatabase sqLiteDatabase) {
try {
String query = "SELECT * FROM tbl_Book WHERE Cat_ID = ?";
Cursor cursor = sqLiteDatabase.rawQuery(query, new String[] {"1"});
if (cursor != null) {
cursor.moveToNext();
}
return cursor;
} catch (SQLException e) {
Log.e("Data Adapter", "getTestData >>" + e.toString());
throw e;
}
}
试试这个:
OnCreateView()
将dataBase = new DataBase(getActivity());
sqLiteDatabase = dataBase.getReadableDatabase();
cursor = sqLiteDatabase.getCat1_Datas2(sqLiteDatabase);
方法修改为:
refreshData()
然后像这样调用它:
public void refreshData(View view){
dataBase = new DataBase(getActivity());
sqLiteDatabase = dataBase.getReadableDatabase();
cursor = dataBase.getCat1_Datas2();
listView = (ListView) view.findViewById(R.id.list);
cat1FragAdapter = new Cat1_frag_adapter(getActivity(), R.layout.list_card_layout);
listView.setAdapter(cat1FragAdapter);
if (cursor.moveToFirst()){
do {
int id, catID, fav;
String title, desvription;
byte[] image;
id = cursor.getInt(0);
title = cursor.getString(2);
dataProvider = new DataProvider(id, title);
cat1FragAdapter.add(dataProvider);
} while (cursor.moveToNext());
}
}
希望它有所帮助!!!