当我在数据库中插入新注册的用户时,我的AddUser()是否应该扩展AsyncTask?

时间:2013-10-06 10:49:29

标签: android android-asynctask

我是否需要将此方法转换为类并扩展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);
    }
}

3 个答案:

答案 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();
    }