我是Android的新手,我除了这个以外几乎了解所有内容 当我使用我的代码只用一个表打开和读取我的数据库它可以工作,但当我尝试将我的数据库更改为另一个更多的表使用相同的代码只是不起作用时,logcat说“无法在30174行打开文件[00bb9c9ce4]“
我使用教程using your own sqlite database in android applications创建了DataBaseHelper
package com.cele.nd.frasesidiomaticas;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by Scarieg on 09/08/2016.
*/
public class BDD extends SQLiteOpenHelper {
private static String DB_PATH = "/data/data/com.cele.nd.frasesidiomaticas/databases/";
private static String DB_NAME = "db_tables.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
private final static int Version = 1;
public static final String KEY_ROWID = "_id";
public BDD(Context context) {
super(context, DB_NAME, null, Version);
this.myContext = context;
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
(SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS));
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* 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.
* */
private 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 outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,(SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS));
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
public Cursor Read(String COLUMN, String Table) {
//includes all column names
String COLUMN_KEY = COLUMN;
String DATABASE_TABLE = Table;
try {
openDataBase();
}catch(SQLException sqle){
throw sqle;
}
Cursor c = myDataBase.rawQuery("SELECT "+KEY_ROWID+", "+COLUMN_KEY+" FROM " + DATABASE_TABLE, null);
return c;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
}
这里就是我称之为
package com.cele.nd.frasesidiomaticas;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import java.io.IOException;
/**
* Created by Scarieg on 03/08/2016.
*/
public class IdiomalistFragment extends Fragment {
View myView;
public BDD myDbHelper = new BDD(getActivity());
public String t;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.idiomalist,container,false);
ListView frases = (ListView)myView.findViewById(R.id.lv_frases);
Bundle b = getArguments();
t = b.getString("Idioma");
TextView Idioma = (TextView)myView.findViewById(R.id.Idioma_TV);
Idioma.setText(t);
try
{myDbHelper.createDataBase();}
catch (IOException ioe)
{throw new Error("Unable to create database");}
try
{myDbHelper.openDataBase();}
catch(SQLException sqle)
{throw sqle;}
String[] from = new String[]{"Frase"};
int[] to = new int[]{R.id.text};
Cursor cursor = myDbHelper.Read("Frase", t);
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.row, cursor, from, to, 1);
frases.setAdapter(cursorAdapter);
frases.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
return myView;
}
@Override
public void onResume(){
super.onResume();
final Spinner spinner_cat = (Spinner) myView.findViewById(R.id.spinnerCat);
String[] from_cat = new String[]{"Categoria"};
int[] to_cat = new int[]{android.R.id.text1};
final Cursor c_cat = myDbHelper.Read("Categoria", t);
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this.getActivity(),android.R.layout.simple_spinner_item, c_cat, from_cat, to_cat, 1);
mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_cat.setPrompt("Selecciona Una Categoria");
spinner_cat.setAdapter(
new NothingSelectedSpinnerAdapter(mAdapter,
R.layout.contact_spinner_row_nothing_selected,
getActivity()));
spinner_cat.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i!=0) {
Cursor c = (Cursor) spinner_cat.getSelectedItem();
String Cat = c.getString(c.getColumnIndex("Categoria"));
Bundle args = new Bundle();
args.putString("Categoria", Cat);
FragmentTransaction t = getActivity().getFragmentManager().beginTransaction();
CategoriaFragment mFrag = new CategoriaFragment();
mFrag.setArguments(args);
t.replace(R.id.content_frame, mFrag);
t.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).show(mFrag);
t.addToBackStack(null).commit();
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
}
这是logcat
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas D/dalvikvm: VFY: replacing opcode 0x6f at 0x000b
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas E/SQLiteLog: (14) cannot open file at line 30174 of [00bb9c9ce4]
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas E/SQLiteLog: (14) os_unix.c:30174: (2) open(/data/data/com.cele.nd.frasesidiomaticas/databases/db_tables.db) -
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas E/SQLiteDatabase: Failed to open database '/data/data/com.cele.nd.frasesidiomaticas/databases/db_tables.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
at com.cele.nd.frasesidiomaticas.BDD.checkDataBase(BDD.java:64)
at com.cele.nd.frasesidiomaticas.BDD.createDataBase(BDD.java:36)
at com.cele.nd.frasesidiomaticas.IdiomalistFragment.onCreateView(IdiomalistFragment.java:44)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
at android.app.BackStackRecord.run(BackStackRecord.java:635)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas D/AndroidRuntime: Shutting down VM
08-16 18:36:45.652 26369-26369/com.cele.nd.frasesidiomaticas W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa62b4288)
08-16 18:36:45.656 26369-26369/com.cele.nd.frasesidiomaticas E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
at com.cele.nd.frasesidiomaticas.BDD.createDataBase(BDD.java:44)
at com.cele.nd.frasesidiomaticas.IdiomalistFragment.onCreateView(IdiomalistFragment.java:44)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
at android.app.BackStackRecord.run(BackStackRecord.java:635)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
希望有人帮助我,并提前致谢
答案 0 :(得分:0)
错误日志指向NullPointerException
- 我怀疑这与初始化db-helper(BDD
)的方式有关。您需要更改并移动第public BDD myDbHelper = new BDD(getActivity());
行。
我的建议是你将声明改为
private BDD myDbHelper;
然后您需要添加onActivityCreated
方法,然后在那里声明BDD
。以下是您可以插入的代码:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myDbHelper = new BDD(getActivity());
}
我怀疑getActivity()
方法可能会导致传递空值,从而导致NullPointerException
。
我希望这个建议有所帮助。