提问人:Ko Wi 提问时间:2/24/2021 更新时间:2/24/2021 访问量:67
尝试访问从 Assets 复制的数据库时出错 - AndroidStudio
Error when trying to access database copied from Assets - AndroidStudio
问:
一整天,我一直在寻找以下错误的根本原因。我那里有谁可以帮助我解决这个问题?
用:Android Studio 4.1.1 / 爪哇
我的目标:我在我的资产文件夹中有一个使用 DB 浏览器 (recipe.db3) 创建的 sqlite 数据库:Assets > recipe.db3。如果该数据库尚不存在(基本上在应用程序生命周期中一次),则应将此数据库复制到 SplashActivity.java 中的应用程序数据库文件夹。 创建后,我想访问此数据库并在 RecipesFragment.java 的 RecycleViewer 中显示其内容(仅标题)。
我的问题:当我尝试显示我的 RecyclerView 时,我收到一个 NullPointerException - 基本上当我在我的 DataBaseHelper.java 中运行 this.getReadableDatabase() 时。似乎我什至无法访问我的数据库。即使我没有将 baking.db3 文件复制到 /data/data/com.android.baking/databases/ 而是以编程方式创建数据库,我也会收到相同的错误。
有没有人知道错误在哪里?
谢谢! 科内利乌斯
Logcat 输出
I/database: TABLE_RECIPES created
TABLE_US created
...............
D/EGL_emulation: eglMakeCurrent: 0xb31050c0: ver 2 0 (tinfo 0xb3103660)
I/art: Do partial code cache collection, code=55KB, data=59KB
After code cache collection, code=54KB, data=58KB
Increasing code cache capacity to 256KB
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.baking, PID: 9878
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.android.baking.ui.recipes.RecipesFragment: calling Fragment constructor caused an exception
at androidx.fragment.app.Fragment.instantiate(Fragment.java:566)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.android.baking.DataBaseHelper.<init>(DataBaseHelper.java:64)
at com.android.baking.ui.recipes.RecipesFragment.<init>(RecipesFragment.java:37)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
数据库助手.java:
package com.android.baking;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.models.RecipeModel;
import com.android.baking.ui.models.UserSpecificModel;
import java.util.ArrayList;
import androidx.annotation.Nullable;
public class DataBaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
public static String DB_NAME = "recipe.db3";
//ITEMS IN TABLE: RECIPES
public static final String TABLE_RECIPES = "RECIPES";
public static final String RECIPE_RECIPE = "RECIPE";
public static final String RECIPE_ID = "ID";
public static final String RECIPE_SOURCE = "SOURCE";
public static final String RECIPE_TITLE = "TITLE";
...............
public static final String RECIPE_ZERO_DOUGH = "ZERO_DOUGH";
public static final String RECIPE_IMAGE_1 = "IMAGE_1";
public static final String RECIPE_IMAGE_2 = "IMAGE_2";
//ITEMS IN TABLE: USER_SPECIFIC
public static final String TABLE_USER_SPECIFIC = "USER_SPECIFIC";
public static final String US_ID = "ID";
public static final String US_URL = "URL";
public static final String US_NOTES = "NOTES";
public static final String US_IS_FAVORITE = "IS_FAVORITE";
public Context context;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
this.getReadableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
//CREATE RECIPES TABLE
String createTableStatement = "CREATE TABLE " + TABLE_RECIPES + " (" + RECIPE_ID + " INTEGER PRIMARY KEY " +
"AUTOINCREMENT, " + RECIPE_SOURCE + " TEXT, " + RECIPE_TITLE + " TEXT, " + RECIPE_URL + " TEXT, " + RECIPE_DATE + " TEXT, " + RECIPE_IMGLINKS + " TEXT, " + RECIPE_DESCRIPTION + " TEXT, " + RECIPE_INGREDIENTS + " TEXT, " + RECIPE_RECIPE + " TEXT, " + RECIPE_PREPTIME_TOTAL + " TEXT, " + RECIPE_PREPTIME_BAKETIME + " TEXT, " + RECIPE_MATCOST + " TEXT, " + RECIPE_OVERNIGHT + " INTEGER, " + RECIPE_FULL_GRAIN + " INTEGER, " + RECIPE_NO_KNEAD + " INTEGER, " + RECIPE_PASTRY_TYPE + " TEXT, " + RECIPE_DOUGHS + " TEXT, " + RECIPE_TASTE + " TEXT, " + RECIPE_PORES + " TEXT, " + RECIPE_FORM + " TEXT, " + RECIPE_ZERO_DOUGH + " TEXT, " + RECIPE_IMAGE_1 + " BLOB, " + RECIPE_IMAGE_2 + " BLOB)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_RECIPES created");
//CREATE USER_SPECIFIC TABLE
createTableStatement =
"CREATE TABLE " + TABLE_USER_SPECIFIC + " (" + US_ID + " INTEGER PRIMARY KEY, " + US_URL + " TEXT, " +
US_NOTES + " TEXT, " + US_IS_FAVORITE + " INTEGER)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_US created");
}
public boolean addOneUS(UserSpecificModel userSpecificModel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(US_URL, userSpecificModel.getUrl());
cv.put(US_NOTES, userSpecificModel.getNote());
cv.put(US_IS_FAVORITE, userSpecificModel.getIs_favorite());
long insert = db.insert(TABLE_USER_SPECIFIC,null, cv);
if (insert == -1) {
return false;
} else {
return true;
}
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
/*SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECIPES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_SPECIFIC);
onCreate(db);*/
}
public ArrayList<RecipeModel> getAllRecipes() {
ArrayList<RecipeModel> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
//String where = " where " + ContentDBManager.KEY_id + " = ? ";
Cursor cursor =
db.rawQuery("SELECT * FROM " + TABLE_RECIPES + " ORDER BY " + RECIPE_TITLE + " DESC", null);
if (cursor != null && cursor.getCount() > 0) {
try {
if (cursor.moveToFirst()) {
do {
RecipeModel recipeModel = new RecipeModel();
recipeModel.setId(cursor.getInt(0));
recipeModel.setSource(cursor.getString(1));
recipeModel.setUrl(cursor.getString(2));
recipeModel.setDate(cursor.getString(3));
recipeModel.setImglinks(cursor.getString(4));
recipeModel.setDescription(cursor.getString(5));
recipeModel.setIngredients(cursor.getString(6));
recipeModel.setRecipe(cursor.getString(7));
recipeModel.setPreptime_total(cursor.getString(8));
recipeModel.setPreptime_baketime(cursor.getString(9));
recipeModel.setMatcost(cursor.getString(10));
recipeModel.setOvernight(cursor.getInt(11));
recipeModel.setFull_grain(cursor.getInt(12));
recipeModel.setNo_knead(cursor.getInt(13));
recipeModel.setPastry_type(cursor.getString(14));
recipeModel.setDoughs(cursor.getString(15));
recipeModel.setTaste(cursor.getString(16));
recipeModel.setPores(cursor.getString(17));
recipeModel.setForm(cursor.getString(18));
recipeModel.setZero_dough(cursor.getString(19));
results.add(recipeModel);
} while (cursor.moveToNext());
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (!cursor.isClosed()){
cursor.close();
}
}
} else {
if (cursor != null) {
Log.i("Database",
"Cursor is Null!");
cursor.close();
}
} // to free up memory of cursor
return results;
}
}
SplashActivity.java:
package com.android.baking.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class SplashActivity extends MainActivity {
private static boolean splashLoaded = false;
private static String DB_PATH;
private static String DB_NAME;
private static final int SPLASH_TIME = 1000;
public final int WRITE_PERMISSION_REQUEST_CODE = 1110;
private final String[] NEEDED_PERMISSIONS = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!checkPermissions(NEEDED_PERMISSIONS)){
ActivityCompat.requestPermissions(SplashActivity.this, NEEDED_PERMISSIONS, WRITE_PERMISSION_REQUEST_CODE);
}else {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
if (!splashLoaded) {
setContentView(R.layout.splash_screen);
int secondsDelayed = 3;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
}, secondsDelayed * SPLASH_TIME);
splashLoaded = true;
} else {
Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(goToMainActivity);
finish();
}
//copy database from assets to database folder if it does not exist
//see also: https://stackoverflow.com/questions/18805874/copy-database-from-assets-to-databases-folder/18806587
if (!doesDatabaseExist(this, DataBaseHelper.DB_NAME)){
DB_PATH = getApplicationInfo().dataDir + "/databases/";
DB_NAME = DataBaseHelper.DB_NAME;
copyDataBase(DB_NAME, DB_PATH);
}
}
private static boolean doesDatabaseExist(Context context, String dbName) {
File dbFile = context.getDatabasePath(dbName);
return dbFile.exists();
}
private void copyDataBase(String dbName, String dbPath)
{
Log.i("Database",
"New database is being copied to device!");
byte[] buffer = new byte[1024];
OutputStream myOutput = null;
int length;
// Open your local db as the input stream
InputStream myInput = null;
try
{
myInput = getApplicationContext().getAssets().open(dbName);
// transfer bytes from the inputfile to the
// outputfile
myOutput = new FileOutputStream(dbPath + dbName);
while((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
myOutput.close();
myOutput.flush();
myInput.close();
Log.i("Database",
"New database has been copied to device!");
}
catch(IOException e)
{
e.printStackTrace();
}
}
// to get FaceFeature and FaceIdFeature.
private boolean checkPermissions(String[] neededPermissions) {
if (neededPermissions == null || neededPermissions.length == 0) {
return true;
}
boolean allGranted = true;
for (String neededPermission : neededPermissions) {
allGranted &= ContextCompat.checkSelfPermission(getApplicationContext(), neededPermission) == PackageManager.PERMISSION_GRANTED;
}
return allGranted;
}
private class BackgroundTask extends AsyncTask {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(Object[] objects) {
try {
Thread.sleep(SPLASH_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Object[] values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case WRITE_PERMISSION_REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == WRITE_PERMISSION_REQUEST_CODE && resultCode == RESULT_OK) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
}
}
配方适配器.java:
package com.android.baking.ui.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.android.baking.R;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
// Create the basic adapter extending from RecyclerView.Adapter
// Note that we specify the custom ViewHolder which gives us access to our views
// see: https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example
public class RecipeAdapter extends
RecyclerView.Adapter<RecipeAdapter.ViewHolder> {
private Context recipeContext;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private ArrayList<RecipeModel> recipeSearchList = new ArrayList<>();
private RecipeItemClickListener recipeListener;
public RecipeAdapter(Context context, ArrayList<RecipeModel> recipeContentList, RecipeItemClickListener listener) {
this.recipeContext = context;
this.recipeListener = listener;
this.recipeList.addAll(recipeContentList);
recipeSearchList.addAll(recipeList);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(recipeContext).inflate(R.layout.item_recycler_view_recipes, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final RecipeModel recipeModel = recipeList.get(position);
holder.tv_title.setText(recipeModel.getTitle());
}
@Override
public int getItemCount() {
return recipeList.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_title;
public ViewHolder(View itemView) {
//ToDo: hier weitermachen
super(itemView);
tv_title = itemView.findViewById(R.id.item_title);
}
}
}
配方片段.java:
package com.android.baking.ui.recipes;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
public class RecipesFragment extends Fragment {
private RecipesViewModel recipesViewModel;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private static RecipesFragment mInstance;
DataBaseHelper dataBaseHelper = new DataBaseHelper(getContext());
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
recipesViewModel = new ViewModelProvider(this).get(RecipesViewModel.class);
View root = inflater.inflate(R.layout.fragment_recipes, container, false);
RecyclerView rec_recipes = root.findViewById(R.id.recipes_recycler_view);
rec_recipes.setLayoutManager(new LinearLayoutManager(getContext()));
recipeList = dataBaseHelper.getAllRecipes();
RecipeAdapter recipeAdapter = new RecipeAdapter(getContext(), recipeList, new RecipeItemClickListener() {
@Override
public void OnItemClicked(RecipeModel recipeModel) {
Toast.makeText(getContext(), "You clicked " + recipeModel.getTitle(), Toast.LENGTH_SHORT).show();
}
});
rec_recipes.setAdapter(recipeAdapter);
return root;
}
}
答:
0赞
user3170251
2/24/2021
#1
在 中,在此处调用它可能会返回 null,因此 NPE。请尝试改为创建 in。RecipieFragment.DataBaseHelper
getContext()
DataBaseHelper
onCreateView()
评论
0赞
Ko Wi
2/24/2021
多谢!这实际上可以消除错误。但是现在,如果我访问数据库,我仍然会收到一个空游标。我在 logcat 中打印了数据库路径 (db.getPath()),似乎该应用程序引用了位于 /data/user/0/com.android.baking/databases/recipes.db3 中的数据库,而不是位于 /data/data/com.android.baking/databases/recipes.db3 中的数据库。为什么它根本不使用我的复制数据库?在设备文件资源管理器中,我什至无法导航到 /data/user/ 目录。
0赞
user3170251
2/24/2021
澄清一下,正确地返回 false,但数据库文件是在其他地方创建的?doesDatabaseExist()
评论