我正在使用Android Studio创建字典App。我试图使用SQlite数据库。
我无法在模拟器上启动它,因为我遇到了2个问题。
"mydirectory"
显示为红色,我不明白如何修复它: -
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
DATABASE_LOCATION = "data/data/" + mContext.getPackageName() +
"/database/";
DATABASE_FULL_PATH = DATABASE_LOCATION + DATABASE_NAME;
if (!isExistingfDB()) {
try {
File dbLocation = new File (DATABASE_LOCATION);
dbLocation = mydirectory();
extractAssetsToDatabaseDirectory(DATABASE_NAME);
} catch (IOException e) {
e.printStackTrace();
}
}
mDB = SQLiteDatabase.openOrCreateDatabase(DATABASE_FULL_PATH, null);
}
"SELECT * FROM "
行并未显示绿色。: -
public ArrayList<String> getWord(int dicType) {
String tableName = getTableName(dicType);
String q = "SELECT * FROM " + tableName;
Cursor result = mDB.rawQuery(q, null);
ArrayList<String> source = new ArrayList<>();
while (result.moveToNext()) {
source.add(result.getString(result.getColumnIndex(COL_KEY)));
}
return source;
}
这是SQLite数据库的结构 i just put it as image
谢谢,我改变了代码,就像在第8步中一样,因为它看起来并不像它显示的那样,并且在Logcat中没有SQLite错误,除了这个:
06-16 19:24:15.406 2925-2925/com.example.dimarozkin.diplomdict E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dimarozkin.diplomdict, PID: 2925
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at com.example.dimarozkin.diplomdict.MainActivity.onPrepareOptionsMenu(MainActivity.java:194)
at android.app.Activity.onPreparePanel(Activity.java:3406)
at android.support.v4.app.FragmentActivity.onPrepareOptionsPanel(FragmentActivity.java:530)
at android.support.v4.app.FragmentActivity.onPreparePanel(FragmentActivity.java:518)
at android.support.v7.view.WindowCallbackWrapper.onPreparePanel(WindowCallbackWrapper.java:98)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onPreparePanel(AppCompatDelegateImplBase.java:359)
at android.support.v7.view.WindowCallbackWrapper.onPreparePanel(WindowCallbackWrapper.java:98)
at android.support.v7.app.ToolbarActionBar$ToolbarCallbackWrapper.onPreparePanel(ToolbarActionBar.java:521)
at android.support.v7.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:455)
at android.support.v7.app.ToolbarActionBar$1.run(ToolbarActionBar.java:55)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
据我所知错误在这里
public boolean onPrepareOptionsMenu(Menu menu) {
String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) {
menuSettings.setVisible(false);
toolbar.findViewById(R.id.edit_search).setVisibility(View.GONE);
toolbar.setTitle("Bookmark");
} else {
menuSettings.setVisible(true);
toolbar.findViewById(R.id.edit_search).setVisibility(View.VISIBLE);
toolbar.setTitle("");
}
return true;
}
但我仍然不知道如何解决它......
答案 0 :(得分:0)
当你遇到困难时,下面是一个匆忙整理的教程和代码。
在SQLite工具中创建数据库和表,根据需要添加数据,然后保存。
关闭数据库并重新打开它以检查表和数据是否符合预期。如果没有进行更改,则重复2,直到您确定保存的数据库匹配为止。
获取已保存数据库的文件名并记录,包括文件扩展名。
如果您还没有为应用创建项目,请执行此操作并保存项目。
在IDE外部导航到项目app / src / main文件夹并创建名为 assets 的文件夹(如果它尚不存在)。
将数据库文件复制到assets文件夹中。
在Android Studio中打开项目。
使用SuperClass创建一个名为 DatabaseHelper 的新Java类作为 SQLiteOpenHelper (将解析为android.database.sqlite.SQLiteOpenHelper
)并勾选显示选择覆盖对话框复选框。单击确定。
应该如下: -
public class DatabaseHelper extends SQLiteOpenHelper {
public Databasehelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
在public class DatabaseHelper extends SQLiteOpenHelper {
之后添加一行作为类变量,如下所示: -
public static final String DBNAME = "my_dic.db";
: -
public static final int DBVERSION = 1;
public static final String TB_BOOKMARK = "Bookmark";
public static final String COL_BOOKMARK_KEY = "key";
public static final String COL_BOOKMARK_VALUE = "value";
public static final String COL_BOOKMARK_DATE = "date";
SQLiteDatabase mDB;
从以下位置更改Databasehelper类的构造函数: -
public DatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){ 超级(上下文,名称,工厂,版本); }
来: -
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
ifDBExists
以检查数据库是否存在(您只想从资产文件中复制一次): -
private boolean ifDBExists(Context context) {
String dbparent = context.getDatabasePath(DBNAME).getParent();
File f = context.getDatabasePath(DBNAME);
if (!f.exists()) {
Log.d("NODB MKDIRS","Database file not found, making directories."); //<<<< remove before the App goes live.
File d = new File(dbparent);
d.mkdirs();
//return false;
}
return f.exists();
}
copyDBFromAssets
将资产文件复制到数据库: -
private boolean copyDBFromAssets(Context context) {
Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
String DBPATH = context.getDatabasePath(DBNAME).getPath();
InputStream is;
OutputStream os;
int length = 8192;
long bytes_read = 0;
long bytes_written = 0;
byte[] buffer = new byte[length];
try {
is = context.getAssets().open(DBNAME);
} catch (IOException e) {
Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
e.printStackTrace();
return false;
}
try {
os = new FileOutputStream(DBPATH);
} catch (IOException e) {
Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
e.printStackTrace();
return false;
}
Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
while (length >= 8192) {
try {
length = is.read(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - RD ASSET",
"Failed while reading in data from the Asset. " +
String.valueOf(bytes_read) +
" bytes read ssuccessfully."
);
e.printStackTrace();
return false;
}
bytes_read = bytes_read + length;
try {
os.write(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
DBPATH +
". " +
String.valueOf(bytes_written) +
" bytes written successfully.");
e.printStackTrace();
return false;
}
bytes_written = bytes_written + length;
}
Log.d("CPYDBINFO",
"Read " + String.valueOf(bytes_read) + " bytes. " +
"Wrote " + String.valueOf(bytes_written) + " bytes."
);
try {
os.flush();
is.close();
os.close();
} catch (IOException e ) {
Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
String.valueOf(bytes_read) +
" bytes read." +
String.valueOf(bytes_written) +
" bytes written."
);
e.printStackTrace();
return false;
}
return true;
}
完整的DatabaseHelper类现在是: -
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "my_dic.db"; // <<<< VERY IMPORTANT THAT THIS MATCHES DATABASE FILE NAME
public static final int DBVERSION = 1;
public static final String TB_BOOKMARK = "Bookmark";
public static final String COL_BOOKMARK_KEY = "key";
public static final String COL_BOOKMARK_VALUE = "value";
public static final String COL_BOOKMARK_DATE = "date";
SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
if (!ifDBExists(context)) {
if (!copyDBFromAssets(context)) {
throw new RuntimeException("Failed to Copy Database From Assets Folder");
}
}
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
private boolean ifDBExists(Context context) {
String dbparent = context.getDatabasePath(DBNAME).getParent();
File f = context.getDatabasePath(DBNAME);
if (!f.exists()) {
Log.d("NODB MKDIRS","Database file not found, making directories.");
File d = new File(dbparent);
d.mkdirs();
//return false;
}
return f.exists();
}
private boolean copyDBFromAssets(Context context) {
Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
String DBPATH = context.getDatabasePath(DBNAME).getPath();
InputStream is;
OutputStream os;
int length = 8192;
long bytes_read = 0;
long bytes_written = 0;
byte[] buffer = new byte[length];
try {
is = context.getAssets().open(DBNAME);
} catch (IOException e) {
Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
e.printStackTrace();
return false;
}
try {
os = new FileOutputStream(DBPATH);
} catch (IOException e) {
Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
e.printStackTrace();
return false;
}
Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
while (length >= 8192) {
try {
length = is.read(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - RD ASSET",
"Failed while reading in data from the Asset. " +
String.valueOf(bytes_read) +
" bytes read ssuccessfully."
);
e.printStackTrace();
return false;
}
bytes_read = bytes_read + length;
try {
os.write(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
DBPATH +
". " +
String.valueOf(bytes_written) +
" bytes written successfully.");
e.printStackTrace();
return false;
}
bytes_written = bytes_written + length;
}
Log.d("CPYDBINFO",
"Read " + String.valueOf(bytes_read) + " bytes. " +
"Wrote " + String.valueOf(bytes_written) + " bytes."
);
try {
os.flush();
is.close();
os.close();
} catch (IOException e ) {
Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
String.valueOf(bytes_read) +
" bytes read." +
String.valueOf(bytes_written) +
" bytes written."
);
e.printStackTrace();
return false;
}
return true;
}
}
copyDBFromAssets
方法),则更改构造函数以运行 ifDBExists
方法: -
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
if (!ifDBExists(context)) {
if (!copyDBFromAssets(context)) {
throw new RuntimeException("Failed to Copy Database From Assets Folder");
}
}
mDB = this.getWritableDatabase();
}
RunTimeExcpetion
已发布而停止。
以下代码还包含一个查询,告诉您数据库中存在哪些表: -
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper mDBHlpr = new DatabaseHelper(this);
Cursor csr = mDBHlpr.getWritableDatabase().query(
"sqlite_master",
null,null,null,null,null,null
);
while (csr.moveToNext()) {
Log.d("DB TABLES", csr.getString(csr.getColumnIndex("name")));
}
csr.close();
}
}
基于屏幕截图和名为 my_dic.db
的数据库文件。日志中的输出是: -
06-16 02:28:45.208 4467-4467/? D/NODB MKDIRS: Database file not found, making directories.
06-16 02:28:45.208 4467-4467/? D/CPYDBINFO: Starting attemtpt to cop database from the assets file.
Initiating copy from asset filemy_dic.db to /data/data/com.mydictionaryapp.mydictionaryapp/databases/my_dic.db
Read 12288 bytes. Wrote 12288 bytes.
06-16 02:28:45.224 4467-4467/? D/DB TABLES: Bookmark
sqlite_autoindex_Bookmark_1
android_metadata
data/data/<package name>/databases
)基本上,对象没有一个名为getClass的方法,而是需要使用Fragment的继承getClass方法。因此,您需要将返回的片段括在括号中。
所以而不是: -
String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
您可以使用: -
String activeFragment = (getSupportFragmentManager().findFragmentById(R.id.fragment_container)).getClass().getSimpleName();
或者你可以使用: -
Fragment activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
以及使用: -
if (activeFragment instanceOf BookmarkFragment) { ...... rest of your code
而不是使用if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ......