如何在不同线程上将一行插入 SQLite 并使用处理程序 return 结果?

How to insert a row into SQLite on a different thread and return the result using handler?

我有这个 SQLite DatabaseHelper 操作,可以将一行插入本地数据库。我想在不同的线程上执行此操作并使用处理程序将结果返回给 UI 线程。我怎样才能做到这一点?下面是操作:

public void insertEmployee(String employeeType, String employeeName, Double employeeConvRate, String employeeDesc) {

    new Thread(() -> {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(EXPENSE_C_TYPE, employeeType);
        values.put(EXPENSE_C_NAME, employeeName);
        values.put(EXPENSE_C_CR, employeeConvRate);
        values.put(EXPENSE_C_DESC, employeeDesc);

        long id = db.insert(EXPENSE_TABLE_NAME, null, values);
        db.close();

    }).start();
}

通常这个函数是一个 public 长的 returns id 变量。

编辑 - 我是怎么做到的:

我用通用参数创建了这个接口:

public interface OnDatabaseResult<T> {
    void onResult(T result);
}

然后我在数据库操作里面添加了handler:

public void insertEmployee(String employeeType, String employeeName, Double employeeConvRate, String employeeDesc) {

    new Thread(() -> {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(EXPENSE_C_TYPE, employeeType);
        values.put(EXPENSE_C_NAME, employeeName);
        values.put(EXPENSE_C_CR, employeeConvRate);
        values.put(EXPENSE_C_DESC, employeeDesc);

        long id = db.insert(EXPENSE_TABLE_NAME, null, values);
        db.close();

    handler.post(()) -> onDatabaseResult.onResult(id)

    }).start();
}

然后在 main activity 中添加了创建行的函数:

public void createEmploye(String employeeType, String employeeName, Double employeeConvRate, String employeeDesc){

     DatabaseHelper databaseHelper = new DatabaseHelper(this);

     databaseHelper.insertEmployee(type, name, rate, desc, new OnDatabaseResult<Long>(){

     @Override
     public void onResult(Long result){
            Employee employee = databaseHelper.getEmployee(result);
            if(employee!=null){
                  employeeList.add(o, employee);
                  employeeAdapter.notifyDataSetChanged();
            }
     }
     });
}

现在可以完美运行了。

试试这个

        new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    SQLiteDatabase db = this.getWritableDatabase();
                    ContentValues values = new ContentValues();

                    values.put(EXPENSE_C_TYPE, employeeType);
                    values.put(EXPENSE_C_NAME, employeeName);
                    values.put(EXPENSE_C_CR, employeeConvRate);
                    values.put(EXPENSE_C_DESC, employeeDesc);

                    long id = db.insert(EXPENSE_TABLE_NAME, null, values);
                    db.close();
                }
            }, 100);

您可以使用 Interface.

以下是基于您的代码的示例,它在另一个线程上插入一个费用行(虽然是同一行但具有不同的 ID)并显示插入的 ID。

接口 MyInterface.java 很简单:-

public interface MyInterface {
    void changeID(long newid);
}

数据库助手 DatabaseHelper.java 是 :-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String EXPENSE_TABLE_NAME = "expense";
    public static final String EXPENSE_C_ID = BaseColumns._ID;
    public static final String EXPENSE_C_TYPE = "type";
    public static final String EXPENSE_C_NAME = "name";
    public static final String EXPENSE_C_CR = "cr";
    public static final String EXPENSE_C_DESC = "description";


    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + EXPENSE_TABLE_NAME + "(" +
                EXPENSE_C_ID + " INTEGER PRIMARY KEY, " +
                EXPENSE_C_TYPE + " TEXT, " +
                EXPENSE_C_NAME + " TEXT," +
                EXPENSE_C_CR + " REAL, " +
                EXPENSE_C_DESC + " TEXT" +
                ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insertEmployee(String employeeType, String employeeName, Double employeeConvRate, String employeeDesc) {

            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues values = new ContentValues();

            values.put(EXPENSE_C_TYPE, employeeType);
            values.put(EXPENSE_C_NAME, employeeName);
            values.put(EXPENSE_C_CR, employeeConvRate);
            values.put(EXPENSE_C_DESC, employeeDesc);

            long id = db.insert(EXPENSE_TABLE_NAME, null, values);
            db.close();
            return id;
    }
}
  • 请注意,insertEmployee 方法并非专门 运行 在另一个线程中(因此更灵活)。

activity、activity_main.xml 的布局非常简单,一个用于显示 id(初始设置为 Hello World)的 TextView 和一个按钮单击时插入新行:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <Button
        android:id="@+id/doit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="DO IT"/>

</LinearLayout>

终于MainActivity.java:-

public class MainActivity extends AppCompatActivity implements MyInterface {

    TextView mShowResult;       // TextView to display the latest id (initially Hello World)
    Button mDoIt;               // The Button, when clicked inserts a new row
    DatabaseHelper mDBHlpr;     // The Database Helper

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mShowResult = this.findViewById(R.id.result); // Get the TextView for the dispaly
        mDoIt = this.findViewById(R.id.doit); // Get the Button
        
        mDBHlpr = new DatabaseHelper(this); // Instantiate the Database Helper
        // Set the Buttons onClick Listener
        mDoIt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                doItInAnotherThread("Full time", "Fred",32.897,"Worker"); //<<<<<<<<<<<
            }
        });
    }

    /**
     * As MainActivity implements MyInterface which has the changeID template
     * the changeID method must be implemented. This will be called when the doItInAnotherThread calls
     * changeID(?).
     *
     * As this is updating a view then it must be run on the UI thread
     */
    public void changeID(final long newid) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mShowResult.setText(String.valueOf(newid));
            }
        });
    }

    /**
     * Do the work in another thread returning changed id via the interface MyInterface
     */
    private void doItInAnotherThread(final String employeeType, final String employeeName, final Double employeeConvRate, final String employeeDesc) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                long id = mDBHlpr.insertEmployee(employeeType, employeeName, employeeConvRate, employeeDesc);
                changeID(id);
            }
        }).start();
    }
}

结果

1。当第一个 运行 :-

2。当单击 DO IT 按钮时(而不是 Hello World,显示屏显示 1