如何在不同线程上将一行插入 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)
我有这个 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();
}
}