java - Android Sqlite - 无法在 onCreate 之外调用数据库处理程序

标签 java android web-services sqlite android-asynctask

所以这是代码:

主要 Activity :

    package com.dummies.myapplication;

import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.sql.SQLClientInfoException;
import java.util.List;
import com.dummies.myapplication.User;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //new LoginHelper().Process();

        DatabaseHandlerV2 db = new DatabaseHandlerV2(this);

        // db.deleteTable();

//       /db.makeTable(DatabaseHandlerV2);

        //Log.d("Insert: ", "Inserting ..");
        db.addUser(new User(1, "name", "email","password","van","username"));


        // Reading all contacts
        Log.d("Reading: ", "Reading all contacts..");
        List<User> users = db.getAllUsers();

        for (User us : users) {
            String log = "Id: "+us.getID()+" ,Name: " + us.getName() + " ,email: " + us.getEmail() + " ,password: " + us.getPassword() + ",username:" + us.getUsername() + ",van:" + us.getVan();
            // Writing Contacts to log
            Log.d("Name: ", log);
        }

        Button login = (Button) findViewById(R.id.loginSubmit);
        final EditText clientUsername = (EditText)findViewById(R.id.username);
        final EditText clientPassword = (EditText)findViewById(R.id.password);

        login.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                //Log.d("User deets username", clientUsername.getText().toString());
                //Log.d("User deets password", clientPassword.getText().toString());
                String username  = clientUsername.getText().toString();
                String password = clientPassword.getText().toString();
                LoginHelper LoginHelper = new LoginHelper();
                LoginHelper.checkLogin(username, password);

            }
        });

        //db.deleteTable();


    }
    public void loginSuccess(String id, String username, String email, String password, String vanId, String name)
    {
        //Log.d("logged in user", id + "," + username + "," + email + "," + password + "," + vanId);
        // db.addUser(new User(id, username, email,password,vanId));
        int intId = Integer.parseInt(id);
        //int intVanId = Integer.parseInt(vanId);
        DatabaseHandlerV2 db = new DatabaseHandlerV2(this);
        db.deleteTableData();
       // db.addUser(new User(intId, name, email,password,vanId,username));
        db.addUser(new User(1, "name", "email","password","van","username"));
        Log.d("Jon Error", "Logged in user is" + intId);

        // db.deleteTable();
    }


}

数据库助手 V2:

package com.dummies.myapplication;

/**
 * Created by Jon on 05/02/2017.
 */

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabaseLockedException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DatabaseHandlerV2 extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "userManager";

    // Contacts table name
    private static final String TABLE_USERS= "users";

    // Contacts Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_PASSWORD = "password";
    private static final String KEY_VAN = "van_id";
    private static final String KEY_USERNAME = "username";


    public DatabaseHandlerV2(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_USERS_TABLE = "CREATE TABLE " + TABLE_USERS + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                + KEY_EMAIL + " TEXT" + "," + KEY_PASSWORD + " TEXT," + KEY_VAN + " INTEGER," + KEY_USERNAME + " TEXT" + ")";

        db.execSQL(CREATE_USERS_TABLE);
        Log.d("Jon error", "creating table");
    }





    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);

        // Create tables again
        onCreate(db);
    }

    /**
     * All CRUD(Create, Read, Update, Delete) Operations
     */

    // Adding new contact
    void addUser(User user) {
        SQLiteDatabase db = this.getWritableDatabase();

        //onCreate(db);

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, user.getName()); // Contact Name
        values.put(KEY_EMAIL, user.getEmail()); // Contact Email
        values.put(KEY_PASSWORD, user.getPassword());
        values.put(KEY_VAN, user.getVan());
        values.put(KEY_USERNAME, user.getUsername());

        // Inserting Row
        db.insert(TABLE_USERS, null, values);
        db.close(); // Closing database connection

    }

    // Getting single contact
    Contact getUser(int id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_USERS, new String[] { KEY_ID,
                        KEY_NAME, KEY_EMAIL, KEY_PASSWORD, KEY_VAN, KEY_USERNAME }, KEY_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
                cursor.getString(1), cursor.getString(2));
        // return contact
        return contact;
    }

    // Getting All Contacts
    public List<User> getAllUsers() {
        Log.d("Jon Error", "debug");
        List<User> userList = new ArrayList<User>();
        // Select All Query
        String selectQuery = "SELECT  * FROM " + TABLE_USERS;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Log.d("Jon Error:", "test");
                User user = new User();
                user.setID(Integer.parseInt(cursor.getString(0)));
                //Log.d(cursor.getString(0));
                user.setName(cursor.getString(1));
                user.setEmail(cursor.getString(2));
                user.setPassword(cursor.getString(3));
                user.setVan(cursor.getString(4));
                user.setUsername(cursor.getString(5));
                // Adding contact to list
                userList.add(user);
            } while (cursor.moveToNext());
        }

        // return contact list
        return userList;
    }

    // Updating single contact
    public int updateUser(User user) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, user.getName());
        values.put(KEY_EMAIL, user.getEmail());
        values.put(KEY_PASSWORD, user.getPassword());
        values.put(KEY_VAN, user.getVan());
        values.put(KEY_VAN, user.getUsername());

        // updating row
        return db.update(TABLE_USERS, values, KEY_ID + " = ?",
                new String[] { String.valueOf(user.getID()) });
    }

    // Deleting single contact
    public void deleteUser(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_USERS, KEY_ID + " = ?",
                new String[] { String.valueOf(contact.getID()) });
        db.close();
    }

    public void deleteTable()
    {
        SQLiteDatabase db = this.getReadableDatabase();
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
        Log.d("Jon error", "deleteing");
    }

    public void deleteTableData()
    {
        SQLiteDatabase db = this.getReadableDatabase();
        db.execSQL("DELETE FROM " + TABLE_USERS);
    }


    // Getting contacts Count
    public int getUsersCount() {
        String countQuery = "SELECT  * FROM " + TABLE_USERS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        cursor.close();

        // return count
        return cursor.getCount();
    }

}

现在我确定问题是因为我正在调用 db.addUser(new User(1, "name", "email","password","van","username"));来自loginSuccess 方法。

如何让这个简单的插入工作?我确信这个问题与上下文有关。我试过了,但没有成功Static way to get 'Context' on Android?

谢谢!

最佳答案

尝试使用单例设计模式来访问数据。 检查这个post出来看看如何。

据我所知,loginSuccess() 在从网络服务器接收数据后被调用。

您的应用可能正在尝试同时将数据写入数据库。

编辑: 使用 DatabaseHandlerV2 的多个实例时,请考虑关闭连接。

示例:

助手:

public class SampleHelper extends SQLiteOpenHelper {

    private static SampleHelper instance;
    private static Context mContext;

    public static synchronized SampleHelper getHelper(Context context) {
        if (instance == null)
             instance = new SampleHelper(context);
        return instance;
    }

    private SampleHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mContext = context;
    }
}

写作:

SampleHelper helper = SampleHelper.getHelper(mContext);
SQLiteDatabase writableDb = helper.getWritableDatabase();
String statement = "INSERT OR REPLACE INTO table_name(colA,colB) VALUES (valA,valB)";
writableDb.execSQL(statement);

阅读:

Cursor cursor = null;
try {    
    cursor = SampleHelper.getHelper(mContext).getReadableDatabase().rawQuery("SELECT colA FROM table_name");
    if (cursor.moveToFirst()) {
        do {
            /**read the data here**/
        } while (cursor.moveToNext());
    }
}
finally {
    if(null != cursor)
        cursor.close();
}

正如您所注意到的,与数据库的连接并未关闭。 使用单例模式时,我们仅使用 SampleHelper 的一个实例,因此我们可以保持连接打开。

直到现在我才检查你更新的日志。它说:

数据库“/data/data/com.dummies.myapplication/databases/userManager”的 SQLiteConnection 对象已泄露!请修复您的应用程序,以正确结束正在进行的事务,并在不再需要数据库时关闭数据库。

这意味着你没有关闭连接(db.close();),因此在上执行this.getReadableDatabase();时出现空指针异常>deleteTableData() 方法。

我仍然建议使用提供的示例代码以避免数据库被锁定异常。

对于 openOrCreateDatabase 异常,请检查此 post 。请注意,数据库名称以 .db 结尾。还要检查您的上下文是否为空。

关于java - Android Sqlite - 无法在 onCreate 之外调用数据库处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42139412/

相关文章:

java - 如何在java中使用 'equality'查询mongodb

java - Web 服务安全 : Client signs SOAP message (Tomcat)

java - 如何将日志发送到 JSON Web 服务?

java - 如何将字符串转换为日历对象?

java - JLS 的哪些部分证明能够像未经检查一样抛出已检查异常?

java - 通过java列出hadoop集群中所有yarn应用

android - 声明 Activity 的目的是什么?

java - Android 应用程序中令人困惑的 java.lang.NullPointerException

android - GCM 是云端点还是独立实体?

javascript - AngularJS:操作 `query` 的资源配置错误。预期响应包含一个对象,但得到一个数组