【发布时间】:2017-03-27 05:00:13
【问题描述】:
我目前正在 Android Studio 上开发一个应用程序,但遇到了一个小问题,希望您能帮助我。此应用程序是使用 Model-View-Presenter 并在 Login 活动(主要活动)中制作的。我调用一个 REST 服务来获取数据并将其保存在数据库中,在交互器类中我有这个方法来将 JSON 对象的数据保存在数据库中
private long insertLoginData() throws JSONException {
HelperDB dbObj = new HelperDB(_ctx);
ContentValues values = new ContentValues();
String firstName = "";
String lastName = "";
values.put(userTableFields[1], _objJson.getString(userTableFields[1]));
if (_objJson.has("fullName")){
JSONObject objFullName = _objJson.getJSONObject("fullName");
firstName = (objFullName.has(userTableFields[2]) ? objFullName.getString(userTableFields[2]) : "");
lastName = (objFullName.has(userTableFields[3]) ? objFullName.getString(userTableFields[3]) : "");
}
values.put(userTableFields[2], firstName);
values.put(userTableFields[3], lastName);
values.put(userTableFields[4], (_objJson.has(userTableFields[4]) ? _objJson.getString(userTableFields[4]) : ""));
values.put(userTableFields[5], true);
values.put(userTableFields[6], _userName);
values.put(userTableFields[7], _Password);
long localId = dbObj.insertStatement(0, values);
dbObj.closeDB();
return localId;
}
_ctx 是 Presenter 中 Context 的局部变量,它来自 Main Activity。 userTableFields 数组包含我的表用户的字段名称,它来自字符串资源。
我知道,这是一种手动方式,我可以使用 POJO 将 JSON 数据的模型转换为类,但这不是问题。我使用调试控制台检查 localId 变量返回的值与 -1 不同,因此记录在数据库中插入正常。
验证用户并将用户记录(用户信息及其通知)插入数据库后,我打开一个新 Activity(第二个 Activity),然后在 Presenter 中调用一个方法来获取用户数据并尝试显示它在这个新活动中。
public class Home extends AppCompatActivity implements HomeView{
private HomePresenter presenter;
private ListView lvNotifications;
private TextView tvWelcome;
private ProgressBar pbHome;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
presenter = new HomePresenterImpl(this);
lvNotifications = (ListView)findViewById(R.id.lvNotifications);
tvWelcome = (TextView)findViewById(R.id.tvWelcome);
pbHome = (ProgressBar)findViewById(R.id.pbHome);
setTitle(getResources().getString(R.string.titleHome));
presenter.getNotificationsDataPresenter(getApplicationContext());
lvNotifications.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//presenter.getSelectedItem(position, _linkResource);
}
});
}
@Override
public void setDataSourceListView(String[] itemArray, String[] linkResource) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, itemArray);
lvNotifications.setAdapter(adapter);
}}
问题就在这里。在第二个活动的 Presenter 中,我调用数据库中的一个方法来获取用户的通知,即使我将句子直接更改为“SELECT * FROM users”,它总是空的,我搜索了很多关于它的主题,但是没有得到解决。
这是获取用户数据的方法,虽然插入在第一个活动中令人满意地发生,但不起作用。
private void getNotificationsData(String query){
HelperDB dbObj = new HelperDB(_ctx);
Cursor cursor = dbObj.getQueryStatement(query, null);
itemArray = new String[cursor.getCount()];
linkResource = new String[cursor.getCount()];
int i = 0;
if (cursor.getCount() > 0)
{
cursor.moveToFirst();
try{
while(cursor.moveToNext()){
itemArray[i] = cursor.getString(0);
linkResource[i] = cursor.getString(1);
i++;
}
}
finally {
cursor.close();
dbObj.close();
}
}
}
我在想这可能是上下文的问题,因为在第一个活动中我执行数据库中的其他函数并且没有问题,但是在第二个活动中返回任何类型的数据,光标没有中断或抛出错误,其变量 mCount 始终为 -1,大小为 0。
以下是我用来连接数据库的 SQLiteOpenHelper。
public class HelperDB extends SQLiteOpenHelper{
private static final String DBName = "MyDb";
private static String createUserTableStatement = "";
private static String createNotificationsTableStatement = "";
String[] tableNames, userTableFields, notificationsTableFields;
public HelperDB(Context context) {
super(context, DBName, null, 1);
tableNames = context.getResources().getStringArray(R.array.tableNames);
userTableFields = context.getResources().getStringArray(R.array.userTableFields);
notificationsTableFields = context.getResources().getStringArray(R.array.notificationsTableFields);
createUserTableStatement = "CREATE TABLE " + tableNames[0] + " (" + userTableFields[0] + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ userTableFields[1] + " TEXT, " + userTableFields[2] + " TEXT, " + userTableFields[3]
+ " TEXT, " + userTableFields[4] + " TEXT, " + userTableFields[5] + " BOOLEAN, " + userTableFields[6] + " TEXT, "
+ userTableFields[7] + " TEXT)";
createNotificationsTableStatement = "CREATE TABLE " + tableNames[1] + " (" + notificationsTableFields[0]
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + notificationsTableFields[1] + " TEXT, "
+ notificationsTableFields[2] + " TEXT, " + notificationsTableFields[3]
+ " TEXT, " + notificationsTableFields[4] + " TEXT, " + notificationsTableFields[5] + " TEXT)";
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(createUserTableStatement);
db.execSQL(createNotificationsTableStatement);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (int i = 0; i < tableNames.length; i++)
db.execSQL("DROP TABLE IF EXISTS " + tableNames[i]);
onCreate(db);
}
public void closeDB() {
SQLiteDatabase db = this.getWritableDatabase();
if (db != null && db.isOpen())
db.close();
}
public long insertStatement(int tableIndex, ContentValues values){
SQLiteDatabase db = this.getWritableDatabase();
long userId;
try{
db.beginTransaction();
userId = db.insert(tableNames[tableIndex], null, values);
db.setTransactionSuccessful();
}
finally {
db.endTransaction();
db.close();
}
return userId;
}
public Cursor getQueryStatement(String queryStatement, String[] fieldsArray){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(queryStatement, fieldsArray);
return cursor;
}
}
问题是,当我想在第二个活动中获取先前在先前活动中插入的数据记录时,我做错了什么?
注意:我总是将 getApplicationContext 作为参数发送给 Presenter,因为 SqliteOpenHelper 中的方法需要构造函数中的上下文。
【问题讨论】:
-
在哪里打电话
getNotificationsData? -
在presenter层(其他类),presenter.getNotificationsDataPresenter(getApplicationContext()); --> 我捕获上下文并将其分配给一个局部变量 --> 在一个变量中我设置了“SELECT * FROM users” --> getNotificationsData(String query)
标签: java android sqlite sqliteopenhelper