【问题标题】:Android: I can´t get data from my database in a second activity using SQLiteOpenHelperAndroid:我无法在第二个活动中使用 SQLiteOpenHelper 从我的数据库中获取数据
【发布时间】: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


【解决方案1】:

你应该像下面的代码一样创建 POJO 类并实现 Parcelable 只需修改你的参数

public class User implements Parcelable {
private Integer id;
private String userName;
private Integer age;


public User() {
}

protected User(Parcel in) {
    userName = in.readString();
    age = in.readInt();
}

public static final Creator<User> CREATOR = new Creator<User>() {
    @Override
    public User createFromParcel(Parcel in) {
        return new User(in);
    }

    @Override
    public User[] newArray(int size) {
        return new User[size];
    }
};

public Integer getId() {

    return id;
}

public Integer getAge() {
    return age;
}

public void setAge(Integer age) {
    this.age = age;
}

public void setId(Integer id) {
    this.id = id;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(userName);
    parcel.writeInt(age);
}

然后使用意图将您的模型放入意图并在您想要的另一个活动中获取意图:

  Intent intent = new Intent(mContext,//your activity name);
            intent.putExtra("yourModekey",userModel);
    startActivities(intent);

在其他活动中得到喜欢

getIntent().getParcelableExtra("yourModelkey");

【讨论】:

  • 在第二个活动中 getQueryStatement(String queryStatement, String[] fieldsArray) 不起作用,如果:第一个活动中的记录没有真正插入,在第一个活动中数据保存在不同的上下文中和使用第二个activity的Context不一样,第二个activity获取数据的方式不对
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多