4

私は最初の Android アプリを開発しており、ユーザーがアプリのログイン ボタンをクリックしているときに進行状況ダイアログを表示したいと考えています。そのため、アプリにasynctaskを統合しました。ログインログアウトなどのすべての操作は正常に完了しましたが、問題は、ログインに成功した後、進行状況ダイアログのためにLoginActivityがウィンドウをリークしたなどのエラーが発生することです。進行状況ダイアログを閉じて UI を更新する方法。

次のコードを参照して、変更点を教えてください

以下はLoginActivityです

public class LoginActivity extends SherlockActivity {
.................
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    sessionmngr = new SessionManager(this);
    //check the user login or not
    if (sessionmngr.isLoggedIn()) {
        Intent checkLoginIntnt = new Intent(this,ProjectFragActivity.class);
        startActivity(checkLoginIntnt);
    }
    setContentView(R.layout.activity_login);
    ........
}
// onclick listener when click on login activity

public void LoginToBookingScape(View v) throws JSONException {

    username = edtTxtUserName.getText().toString();
    userpsw = edtTxtUserPsw.getText().toString();

    if ((username.trim().length() > 0)&&(userpsw.trim().length() > 0)) {

        JsonWebService jsonWebs = new JsonWebService();
        jsonWebs.execute(loginUrl);

    }else {
        ............
    }   
}

以下は、LoginActivity で AsyncTask を拡張する内部クラスです。

private class JsonWebService extends AsyncTask<String,Void,String> {

    private ProgressDialog dialogLogin;
    @Override
    protected String doInBackground(String... url) {

                httpPost.setEntity(new UrlEncodedFormEntity(params));
                ....
                inStream = httpEntity.getContent();
                .........
                return jsonResp;
    }

    @Override
    protected void onPostExecute(String jsonData) {
        //get string data from doinBackground
        try {
            JSONObject jsonObj = new JSONObject(jsonData);
            String key_login = jsonObj.getString(KEY_LOGIN);

            if (key_login.equalsIgnoreCase("0")) {
                .............

            }else {
                ....
                sessionmngr = new SessionManager(getApplicationContext());

                sessionmngr.createLoginSession(id,jsonObj.getString(KEY_UNAME), 
                        jsonObj.getString(KEY_UEMAIL));

                dialogLogin = ProgressDialog.show(LoginActivity.this, "Bookingscape", 
                        "Please Wait",true);
                dialogLogin.setIcon(R.drawable.icon);
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(4000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

                Intent inteProj = new Intent(getApplicationContext(),           

                    ProjectFragActivity.class);
                startActivity(inteProj);
                finish();   
            }
        ........
    }
    @Override
    protected void onCancelled() {
        dialogLogin.dismiss();
        dialogLogin = null;
        super.onCancelled();
    }
}

}

ここで一つ質問したい

上記のコードが最適化され、再利用可能です。

前もって感謝します

4

4 に答える 4

11

問題は、進捗ダイアログを閉じずに新しいアクティビティに移動していることです。これにより、リークウィンドウエラーが発生します

コード内でdialogLogin.dismiss();フォームonCancelled()ブロックを ブロックに移動する必要があると思いますonPostExecute

別のアクティビティに行く前に、これを行う必要があります。つまり前に

Intent inteProj = new Intent(getApplicationContext(),ProjectFragActivity.class);
startActivity(inteProj);

このコード行。これで問題が解決すると思います

1つの疑問: onPreExecute はどこにありますか?? 通常、そのブロックに進行状況コードを表示し、onPostExecute でそれを却下します

だいたいの流れはこんな感じonPreExecute-->doInBackground --->onPostExecute

編集 :

onPreExecute: UI コンポーネントを初期化します (例: ダイアログ) ProgressDialog

doInBackground :onPreExecuteブロック制御がこのブロックに移動した後、これは動作しますProgressDialog

onPostExecute : すべてのバックグラウンド アクションの後にコントロールがここに来ます。ここでProgressDialog、新しいアクティビティを閉じて移動できます。

于 2013-04-23T09:44:43.503 に答える
0

おそらくそれはあなたが書いているからです

Intent inteProj = new Intent(getApplicationContext(),           
ProjectFragActivity.class);
startActivity(inteProj);

ダイアログを閉じる前に、アクティビティが変更されてもダイアログがまだプロセスを表示していることを意味します。だからちょうどあなたを置く

dialogLogin.dismiss();
dialogLogin = null;

この前の行

Intent inteProj = new Intent(getApplicationContext(),           
ProjectFragActivity.class);
startActivity(inteProj);

その後、この問題は解決されます。

于 2013-11-26T05:59:42.540 に答える
0

私もこの問題を抱えていましたが、これが原因です。私のアプリは入力を受け取り、それらを SQLite データベースに追加します。これは私が持っていたものです:

 public Item doInBackground(String...params) {
       Item item = new Item();
        try {

            item.setItemName(params[0]);
            item.setSupplierPhone(params[1]);
            ...
            databaseHandler.addItem(item);

            //Toast.makeText(mContext, "Item successfully saved.", Toast.LENGTH_SHORT).show();

            databaseHandler.close();


        } catch (SQLiteException e) {
            Toast.makeText(mContext, "Error saving Item!", Toast.LENGTH_SHORT).show();
        }
        return item;
    }

これは、実行パスが既に入っていた後にダイアログを表示しようとしていたためだと思いますonPostExecute()

この例外がスローされる理由は多数あることに注意することも重要です。それらの多くはここで議論されています

于 2015-06-03T10:29:01.903 に答える