Android:由于进度对话框,活动已泄露窗口?

时间:2013-04-23 09:31:30

标签: android

我正在开发我的第一个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的Inner类

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 个答案:

答案 0 :(得分:11)

问题是你在不放弃进度对话的情况下转向新的活动。这将导致泄露的窗口错误

我认为您必须在代码中将dialogLogin.dismiss();表单onCancelled()阻止移动到onPostExecute阻止

你必须在去另一项活动之前这样做。即在

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

这行代码。我认为这将解决您的问题

一个疑问:你的onPreExecute在哪里?通常我会在该块中显示进度代码并在onPostExecute

中将其关闭

通常流程就像这个onPreExecute-->doInBackground --->onPostExecute

编辑:

onPreExecute:初始化您的UI组件(例如:Dialoges)。在您的情况下ProgressDialog出现

doInBackground:在onPreExecute块控制转到此块之后,这将是。ProgressDialog继续它的工作

onPostExecute:控制在所有后台操作后来到这里。在这里你可以解雇你的ProgressDialog并转到你的新活动。

答案 1 :(得分:0)

可能是因为你正在撰写

Intent inteProj = new Intent(getApplicationContext(),           
ProjectFragActivity.class);
startActivity(inteProj);
解除对话框之前

表示即使您的活动已更改,您的对话框仍会显示进程。所以只需把你的

dialogLogin.dismiss();
dialogLogin = null;

之前的行

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

然后这个问题就会得到解决。

答案 2 :(得分: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()

之后显示一个Dialog

同样重要的是要注意抛出此异常的原因有很多。 讨论了很多here

答案 3 :(得分:0)

在转发到下一个活动之前,您需要关闭该对话框。 使用:- dialog.dismiss();