0

このメソッドを使用するには、このメソッドをクラスにして AsyncTask を拡張する必要がありますか? どこかで、UI スレッドから DB 操作を実行するべきではないと読んだことがありますか?

もしそうなら、どうすればそれを行うことができますか?

コード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);
    }
}
4

3 に答える 3

1

ドキュメントから:

AsyncTasks は、理想的には短い操作 (最大で数秒) に使用する必要があります。AsyncTask を使用すると、UI スレッドを適切かつ簡単に使用できます。このクラスを使用すると、スレッドやハンドラーを操作することなく、バックグラウンド操作を実行し、UI スレッドで結果を公開できます。 ここ

ネットワーク タスクのような単純なものでは、データベースの処理は、メインの UI スレッドではなく別のスレッドで処理する必要があります。

あなたの質問について:はい、Aysncタスクを使用してください

あなたが上に書いたことはほぼ正しいです:

最初のパラメーターは、でアクセス可能な文字列の配列を渡すか、前に HashMap を作成して最初のパラメーターとしてハッシュマップを渡すには、String である必要がありprotected Void doInBackground(String... strings) {ますstrings[0] = userName etc...。空の 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 を呼び出します。

new AddNewContact().execute(userName, email, etc...);

ユーザーにa を表示したい場合はprogress dialog、次のように onPreExecute と onPostExecute をオーバーライドできます。

@Override
    protected void onPreExecute() {
        progressDialog.show();
        progressDialog.setCancelable(false);
    }

@Override
    protected void onPostExecute(JSONObject json) {
           progressDialog.dismiss();
    }
于 2013-10-06T10:59:16.773 に答える
1

ほとんどの場合、はい。

すべての View コールバック (onClick など) はメイン スレッドで実行されます。ディスクやネットワークに触れるものがメインスレッドでも実行されないようにする必要があります。特に、DB アクセス、ネットワーキング、ファイルの読み取り/書き込み、および長時間実行される計算は、すべて別のスレッドで実行する必要があります (たとえば、 を使用AsyncTask)。

しかし、あなたは2つの間違ったことをしています。

1)操作のパラメーター(ユーザー名、パスワードなど)を渡していません。Paramsテンプレート引数 (最初のもの) を に設定するStringと、 の署名が得られますVoid doInBackground(String.. params)。こうすることで、操作の概念が、現在挿入している特定の値から切り離されます。

2) 失敗を抑えている。その try-empty-catch-all ブロッ​​クは本当に悪い習慣であり、避けるべきです。結果タイプをブール値に変更し、両方の結果を で処理できますonPostExecute

于 2013-10-06T10:56:18.463 に答える