使用片段从数据库 SQLite 获取数据时出错
Posted
技术标签:
【中文标题】使用片段从数据库 SQLite 获取数据时出错【英文标题】:Error When Fetch data from database SQLite with fragment 【发布时间】:2018-02-24 03:12:27 【问题描述】:这是我的片段活动,我在访问数据库时遇到错误我的代码是:
public class RainfallFragment extends Fragment
public static final String KEY_DIVISION_ID="division_id";
public static final String KEY_DIVISION_NAME="division_name";
ListView listCollege;
ProgressBar proCollageList;
public Context context;
private mysqliteHelper dbHelper;
public RainfallFragment()
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
dbHelper = new MySQLiteHelper(getActivity());
// dbHelper = new MySQLiteHelper(this);
dbHelper.getReadableDatabase();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
// Inflate the layout for this fragment
getActivity().setTitle("Rainfall Report");
getActivity().setTitleColor(0000000);
View v =inflater.inflate(R.layout.fragment_rainfall, container, false);
context = v.getContext();
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_DOWN)
if (keyCode == KeyEvent.KEYCODE_BACK)
getActivity().finish();
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
return true;
return false;
);
//DISINI BATAS NYA//
listCollege = (ListView)v.findViewById(R.id.listCollege);
proCollageList = (ProgressBar)v.findViewById(R.id.proCollageList);
new GetHttpResponse().execute();
listCollege.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener()
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3)
// On selecting single row to get detail information
final String division_id = ((TextView) view.findViewById(R.id.adapter_text_id)).getText().toString();
final String division_name = ((TextView) view.findViewById(R.id.adapter_text_estate)).getText().toString();
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
b.setIcon(android.R.drawable.ic_dialog_alert);
b.setMessage("Sure for choosing this estate");
b.setPositiveButton("OK", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton)
Intent i = new Intent(getActivity(), RainfallReport.class);
i.putExtra(KEY_DIVISION_ID, division_id);
i.putExtra(KEY_DIVISION_NAME, division_name);
getActivity().startActivity(i);
dialog.dismiss();
);
b.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton)
);
b.show();
);
return v;
private class GetHttpResponse extends AsyncTask<Void, Void, Void>
private Context context;
String result;
List<HashMap<String, String>> collegeList;
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Void doInBackground(Void... arg0)
List<Estate> estates = new LinkedList<Estate>();
estates= dbHelper.getAllEstate();
//Syntax for sort Listview Array by Id Ascending
Collections.sort(estates, new Comparator<Estate>()
@Override
public int compare(Estate id1,Estate id2)
return id1.getDivision_id() - id2.getDivision_id();
);
// looping through All data
for(Estate temp_vg: estates)
temp_vg.getDivision_id();
temp_vg.getDivision_name();
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("division_id", String.valueOf(temp_vg.getDivision_id()));
map.put("division_estate", temp_vg.getDivision_name());
// adding HashList to ArrayList
collegeList.add(map);
return null;
@Override
protected void onPostExecute(Void result)
proCollageList.setVisibility(View.GONE);
listCollege.setVisibility(View.VISIBLE);
if(collegeList != null)
//adapter = new ListAdapterEstate(LihatDataEstate.this, map);
ListAdapterEstate adapter = new ListAdapterEstate(collegeList, context);
listCollege.setAdapter(adapter);
//adapter=new LazyAdapter(Lihat_Data.this, dataList);
//list.setAdapter(adapter);
MySQLiteHelper.java
public class MySQLiteHelper extends SQLiteOpenHelper
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "AARIDB.db";
private SQLiteDatabase database;
public MySQLiteHelper(Context context)
super(context, "/mnt/sdcard/AARIDB/DBAARI.db", null, DATABASE_VERSION);
//super(context, DATABASE_NAME, null, DATABASE_VERSION);
String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
"division_id INTEGER PRIMARY KEY, " +
"year_rainfall VARCHAR (5), "+
"jan VARCHAR (10), "+
"feb VARCHAR (10),"+
"mar VARCHAR (10),"+
"apr VARCHAR (10),"+
"may VARCHAR (10),"+
"jun VARCHAR (10),"+
"jul VARCHAR (10),"+
"aug VARCHAR (10),"+
"sep VARCHAR (10),"+
"oct VARCHAR (10),"+
"nov VARCHAR (10),"+
"dec VARCHAR (10),"+
" FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
// create table
db.execSQL(RAINFALL_TABLE);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
// Drop older books table if existed
db.execSQL("DROP TABLE IF EXISTS rainfall");
// create fresh books table
this.onCreate(db);
//---------------------------------------------------------------------
/**
* CRUD operations (create "add", read "get", update, delete) book + get all + delete all
*/
private static final String TABLE_RAINFALL = "rainfall";
// assesment Table Columns names
public static final String KEY_DIVISION_ID_RAINFALL= "division_id";
public static final String KEY_YEAR_RAINFALL= "year_rainfall";
public static final String KEY_JAN_RAINFALL = "jan";
public static final String KEY_FEB_RAINFALL = "feb";
public static final String KEY_MAR_RAINFALL = "mar";
public static final String KEY_APR_RAINFALL = "apr";
public static final String KEY_MAY_RAINFALL = "may";
public static final String KEY_JUN_RAINFALL = "jun";
public static final String KEY_JUL_RAINFALL = "jul";
public static final String KEY_AUG_RAINFALL = "aug";
public static final String KEY_SEP_RAINFALL = "sep";
public static final String KEY_OCT_RAINFALL = "oct";
public static final String KEY_NOV_RAINFALL = "nov";
public static final String KEY_DEC_RAINFALL = "dec";
private static final String[] COLUMN_RAINFALL =
KEY_DIVISION_ID_RAINFALL,
KEY_YEAR_RAINFALL,
KEY_JAN_RAINFALL,
KEY_FEB_RAINFALL ,
KEY_MAR_RAINFALL ,
KEY_APR_RAINFALL,
KEY_MAY_RAINFALL,
KEY_JUN_RAINFALL,
KEY_JUL_RAINFALL,
KEY_AUG_RAINFALL,
KEY_SEP_RAINFALL,
KEY_OCT_RAINFALL ,
KEY_NOV_RAINFALL ,
KEY_DEC_RAINFALL;
public void addRAINFALL(Rainfall rainfall)
Log.d("addRAINFALL", rainfall.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_DIVISION_ID_RAINFALL, rainfall.getDivision_id()); // get est
values.put(KEY_YEAR_RAINFALL, rainfall.getYear_rainfall());
values.put(KEY_JAN_RAINFALL , rainfall.getJan());
values.put(KEY_FEB_RAINFALL, rainfall.getFeb());
values.put(KEY_MAR_RAINFALL, rainfall.getMar()); // get estate name
values.put(KEY_APR_RAINFALL, rainfall.getApr());
values.put(KEY_MAY_RAINFALL, rainfall.getMay());
values.put(KEY_JUN_RAINFALL, rainfall.getJun());
values.put(KEY_JUL_RAINFALL, rainfall.getJul()); // get estate name
values.put(KEY_AUG_RAINFALL, rainfall.getAug());
values.put(KEY_SEP_RAINFALL, rainfall.getSep());
values.put(KEY_OCT_RAINFALL , rainfall.getOct()); // get estate name
values.put(KEY_NOV_RAINFALL,rainfall.getNov());
values.put(KEY_DEC_RAINFALL, rainfall.getDec());
// 3. insert
db.insert(TABLE_RAINFALL, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
public List<Rainfall> getAllRainfall()
List<Rainfall> rainfall = new LinkedList<Rainfall>();
// 1. build the query
String query = "SELECT * FROM " + TABLE_RAINFALL+" ORDER BY "+KEY_DIVISION_ID_RAINFALL;
// 2. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
// 3. go over each row, build book and add it to list
Rainfall rainfall1 = null;
if (cursor.moveToFirst())
do
rainfall1 = new Rainfall();
rainfall1.setDivision_id(Integer.parseInt(cursor.getString(0)));
rainfall1.setYear_rainfall(cursor.getString(1));
rainfall1.setJan(cursor.getString(2));
rainfall1.setFeb(cursor.getString(3));
rainfall1.setMar(cursor.getString(4));
rainfall1.setApr(cursor.getString(5));
rainfall1.setMay(cursor.getString(6));
rainfall1.setJun(cursor.getString(7));
rainfall1.setJul(cursor.getString(8));
rainfall1.setAug(cursor.getString(9));
rainfall1.setSep(cursor.getString(10));
rainfall1.setOct(cursor.getString(11));
rainfall1.setNov(cursor.getString(12));
rainfall1.setDec(cursor.getString(13));
// Add vgm
rainfall.add(rainfall1);
while (cursor.moveToNext());
return rainfall;
public Cursor getAllDataRainfall()
SQLiteDatabase db=this.getWritableDatabase();
Cursor mCursor = db.query("SELECT year_rainfall, jan, feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec FROM rainfall",
new String[] KEY_YEAR_RAINFALL,KEY_JAN_RAINFALL,KEY_FEB_RAINFALL,KEY_MAR_RAINFALL,KEY_APR_RAINFALL,KEY_MAY_RAINFALL,
KEY_JUN_RAINFALL,KEY_JUL_RAINFALL,KEY_AUG_RAINFALL,KEY_SEP_RAINFALL,KEY_OCT_RAINFALL,KEY_NOV_RAINFALL,KEY_DEC_RAINFALL,
null, null, null, null, null);
if (mCursor != null)
mCursor.moveToFirst();
db.close();
return mCursor;
我只需要在片段中访问数据库。任何人都会帮助我,我将不胜感激。错误的日志猫如下。
注意! at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)
指的是dbHelper.getReadableDatabase();
09-14 22:20:16.387 1247-1247/com.test.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.myapplication, PID: 1247
java.lang.NullPointerException
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2068)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1055)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
您的问题暗示该问题与从您的片段访问数据库有关。你确认是这样的吗?尝试从其他地方(活动、应用程序类...)访问数据库,看看是否遇到相同的错误。 请编辑您的问题以清楚地表明这指的是哪一行at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)
。您的 TABLE CREATE SQL 有错误,它应该等于 CREATE TABLE rainfall (division_id INTEGER PRIMARY KEY, year_rainfall VARCHAR (5), jan VARCHAR (10), feb VARCHAR (10), mar VARCHAR (10), apr VARCHAR (10), may VARCHAR (10), jun VARCHAR (10), jul VARCHAR (10), aug VARCHAR (10), sep VARCHAR (10), oct VARCHAR (10), nov VARCHAR (10), dec VARCHAR (10), FOREIGN KEY (division_id) REFERENCES ESTATE_TABLE progress(division_id));
...
那是围绕 division_id 的括号(两者)和最后一个右括号。修复后,您应该 a) 卸载应用程序,b) 清除应用程序的数据或 c) 增加版本号,然后重新运行应用程序。不知道这是否是原因。
错误是指dbHelper.getReadableDatabase();
堆栈跟踪是因为将 null 或其他无效的上下文传递给 SQLiteOpenHelper。您发布的代码甚至无法编译,因此不会导致该堆栈跟踪。
【参考方案1】:
我无法设置您的 MySQLiteHelper 的 onCreate。你需要放
String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
"division_id INTEGER PRIMARY KEY, " +
"year_rainfall VARCHAR (5), "+
"jan VARCHAR (10), "+
"feb VARCHAR (10),"+
"mar VARCHAR (10),"+
"apr VARCHAR (10),"+
"may VARCHAR (10),"+
"jun VARCHAR (10),"+
"jul VARCHAR (10),"+
"aug VARCHAR (10),"+
"sep VARCHAR (10),"+
"oct VARCHAR (10),"+
"nov VARCHAR (10),"+
"dec VARCHAR (10),"+
" FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
// create table
db.execSQL(RAINFALL_TABLE);
在你的 MySQLiteHelper 的 onCreate 中创建这样的表
@Override
public void onCreate(SQLiteDatabase db)
String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
"division_id INTEGER PRIMARY KEY, " +
"year_rainfall VARCHAR (5), "+
"jan VARCHAR (10), "+
"feb VARCHAR (10),"+
"mar VARCHAR (10),"+
"apr VARCHAR (10),"+
"may VARCHAR (10),"+
"jun VARCHAR (10),"+
"jul VARCHAR (10),"+
"aug VARCHAR (10),"+
"sep VARCHAR (10),"+
"oct VARCHAR (10),"+
"nov VARCHAR (10),"+
"dec VARCHAR (10),"+
" FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
// create table
db.execSQL(RAINFALL_TABLE);
【讨论】:
【参考方案2】:我已经解决了这个问题.. 只需更改我在 RainfallFragment 中的代码
来自:
List<HashMap<String, String>> collegeList;
到:
ArrayList<HashMap<String, String>> collegeList = new ArrayList<HashMap<String, String>>();
进入我的 Asynctask RainfallFargment 。
【讨论】:
【参考方案3】:像MySQLiteHelper
一样更改它:
public class MySQLiteHelper
private SQLiteDatabase db;
private Context context;
private DBHelper dbHelper;
public MySQLiteHelper(Context context)
dbHelper = new DBHelper(context);
public MySQLiteHelper open() throws SQLException
db = dbHelper.getWritableDatabase();
return this;
public void close()
dbHelper.close();
public class DBHelper extends SQLiteOpenHelper
public DBHelper(Context context)
super(context, "/mnt/sdcard/AARIDB/DBAARI.db", null, 1);
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL(RAINFALL_TABLE);//create tables
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL("DROP TABLE IF EXISTS rainfall"); //drop tables if exists and than create or alter
this.onCreate(db);
来自其他activity
的电话:
MySQLiteHelper db = new MySQLiteHelper(MainActivity.this);
【讨论】:
不兼容的类型。必需:android.database.sqlite.SQLiteDatabase 找到:com.test.myapplication.MySQLiteHelper :((仍然错误) 无限递归不是答案 对不起,我不明白@laalto 我也不了解您的解决方案@AmitVaghela 你建议让构造函数创建一个新对象,然后再次调用相同的构造函数。以上是关于使用片段从数据库 SQLite 获取数据时出错的主要内容,如果未能解决你的问题,请参考以下文章
当我从用户获取数据并将其保存到 SQLite 数据库中时,我应该怎么做才能使列表视图在片段中工作
从 2 个不同片段的 sqlite 中的 2 个表中获取信息
如何使用光标和循环显示来自 sqlite 的片段的 recyclerview