我是否需要将此方法转换为类并扩展AsyncTask才能使用它? 在某处我读过,我永远不应该从UI线程运行数据库操作?
如果是这样,我该怎么做呢?
以下是代码ATM:
public void addNewContact() {
HashMap<String, String> queryValuesMap = new HashMap<String, String>();
queryValuesMap.put("userName", userName);
queryValuesMap.put("userEmail", userEmail);
queryValuesMap.put("userPassword", userPassword);
queryValuesMap.put("userAvatar", userAvatar);
queryValuesMap.put("userSex", userSex);
dbTools.insertUser(queryValuesMap);
dbTools.close();
}
然后从我的提交按钮onClick()调用它。
我想我应该做的是以下几点:
private class AddNewContact extends AsyncTask <Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
try {
HashMap<String, String> queryValuesMap = new HashMap<String, String>();
queryValuesMap.put("userName", userName);
queryValuesMap.put("userEmail", userEmail);
queryValuesMap.put("userPassword", userPassword);
queryValuesMap.put("userAvatar", userAvatar);
queryValuesMap.put("userSex", userSex);
dbTools.insertUser(queryValuesMap);
dbTools.close();
} catch (Exception e) {}
return null;
}
}
然后在提交按钮onClick()上添加AddNewContact.execute()。
这是对的吗?
编辑:以下是实施以下讨论中接受的答案后的工作代码:
onClick中的:
AddNewUserParams addNewUserParams = new AddNewUserParams();
addNewUserParams.userName = this.userName;
addNewUserParams.userEmail = this.userEmail;
addNewUserParams.userPassword = this.userPassword;
addNewUserParams.userAvatar = this.userAvatar;
addNewUserParams.userSex = this.userSex;
new AddNewContact().execute(addNewUserParams);
以下是嵌套类:
private class AddNewUserParams {
String userName;
String userEmail;
String userPassword;
String userAvatar;
String userSex;
}
private class AddNewContact extends AsyncTask <AddNewUserParams, Void, Void> {
@Override
protected Void doInBackground(AddNewUserParams... params) {
try {
HashMap<String, String> queryValuesMap = new HashMap<String, String>();
queryValuesMap.put("userName", params[0].userName);
queryValuesMap.put("userEmail", params[0].userEmail);
queryValuesMap.put("userPassword", params[0].userPassword);
queryValuesMap.put("userAvatar", params[0].userAvatar);
queryValuesMap.put("userSex", params[0].userSex);
dbTools.insertUser(queryValuesMap);
dbTools.close();
} catch (Exception e) {
toastMaker.toast(net.asdqwe.activities.Signup.this, configurationz.ERROR_MESSAGES_SIGNUP_USER_NOT_CREATED, configurationz, Toast.LENGTH_LONG);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
Intent signupSuccessHome = new Intent(getApplicationContext(), Home.class);
signupSuccessHome.putExtra(EXTRA_MESSAGE, userEmail);
startActivity(signupSuccessHome);
super.onPostExecute(result);
}
}
答案 0 :(得分:1)
除非您在UI线程中进行长时间操作,否则不应该从UI线程运行数据库操作 正确。这样做的主要原因不是减慢UI线程。当您在数据库中插入一个非常小的值时,您可以毫无顾虑地使用您的代码,但习惯使用异步任务将数据插入/检索到数据库中,以免降低UI线程的速度。
答案 1 :(得分:1)
主要是,是的。
所有View回调(onClick等)都在主线程上执行。您应该确保在主线程上也没有任何触及磁盘或网络的内容。特别是,数据库访问,网络,文件读/写和长时间运行的计算都应该在不同的线程上进行(例如,使用AsyncTask
)。
1)您没有传递操作的参数(用户名,密码等)。您可以将Params
模板参数(第一个)设置为String
,这将为您提供Void doInBackground(String.. params)
的签名。这样,操作的想法就与您当前可能插入的特定值分开。
2)你正在压制失败。那个try-empty-catch-all块是一个非常非常糟糕的做法,你应该避免它。您可以将结果类型更改为布尔值,然后在onPostExecute
中处理两个结果。
答案 2 :(得分:1)
来自文档:
理想情况下,AsyncTasks应该用于简短操作(最多几秒钟。)AsyncTask可以正确,方便地使用UI线程。此类允许执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。 here
在网络任务这样的简单事情中,数据库处理应该在单独的线程而不是主UI线程中处理。
关于你的问题:是的,使用Aysnc任务
您上面写的内容几乎是正确的:
第一个参数需要是String,以传递protected Void doInBackground(String... strings) {
strings[0] = userName etc...
中可访问的字符串数组,或者在之前创建HashMap并将hashmap作为第一个参数传递。拥有空的catch块也是不好的做法,你应该至少记录一个错误。
添加代码
@Override
protected Void doInBackground(String... params) {
try {
HashMap<String, String> queryValuesMap = new HashMap<String, String>();
queryValuesMap.put("userName", params[0]);
queryValuesMap.put("userEmail", params[1]);
queryValuesMap.put("userPassword", params[2]);
queryValuesMap.put("userAvatar", params[3]);
queryValuesMap.put("userSex", params[4]);
dbTools.insertUser(queryValuesMap);
dbTools.close();
} catch (Exception e) {}
return null;
您可以这样称呼新的Async Class
:
new AddNewContact().execute(userName, email, etc...);
如果您想向用户显示progress dialog
,您可以覆盖onPreExecute和onPostExecute,如下所示:
@Override
protected void onPreExecute() {
progressDialog.show();
progressDialog.setCancelable(false);
}
@Override
protected void onPostExecute(JSONObject json) {
progressDialog.dismiss();
}