1

我正在处理 AsyncTask 以登录服务器,但是当我尝试在其中显示 progressdialog 时遇到错误。但是,它之前确实运行良好。这是我的代码。

登录活动.java

public class LoginActivity extends Activity {
public void loginButtonClick(View view) {
  //TODO.Validatioin check here

  LoginTask loginTask = new LoginTask();
  loginTask.execute(app.getPortalWsUrl(app.AUTHENTICATION_URI) , getUserId(), getPassword());
}

private class LoginTask extends AsyncTask<String, String, JsonResult<Subscriber>> {

        private SimpleHttpClient mClient;
        private ProgressDialog mDialog;

        public LoginTask(){
            this.mClient = new SimpleHttpClient();
            this.mDialog = new ProgressDialog(LoginActivity.this);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mDialog.setTitle(R.string.m_logging);
            mDialog.setMessage(LoginActivity.this.getString(R.string.m_wait));
            mDialog.show();
        }

        @Override
        protected JsonResult<Subscriber> doInBackground(String... params) {
            JsonResult<Subscriber> jsonResult = new JsonResult<Subscriber>();

            if (params.length!=3) {
                //jsonResult.setMessage("Invalid arguments to call method.");
                return null;
            }

            String url  = params[0];
            String userId   = params[1];
            String password = params[2];

            try {
                StringBuilder sb = new StringBuilder();
                sb.append(url)
                  .append("?")
                  .append("userid=").append(userId)
                  .append("&")
                  .append("password=").append(password);

                String receivedText = mClient.postJson(sb.toString(), "");

                JSONObject jsonObj = new JSONObject(receivedText);
                jsonResult.setOk(jsonObj.optBoolean("ok"))
                          .setMessage(jsonObj.optString("message"));

                if (jsonResult.isOk()){
                    JSONObject result = jsonObj.optJSONObject("result");
                    SubscriptionService service = parseResult(result);
                    Subscriber subsriber = new Subscriber();
                    subsriber.userId = userId;
                    subsriber.password = "";
                    subsriber.userName = result.optString("accountHolder");
                    subsriber.service = service;
                    jsonResult.setResult(subsriber);
                }

            } catch (Exception e) {
                logger.error(e.getMessage()); //==>This was problem.
                jsonResult.setOk(false).setMessage(e.getMessage());
            }

            logger.debug("###JsonResult###" + jsonResult);

            return jsonResult;
        }

        @Override
        protected void onPostExecute(JsonResult<Subscriber> result) {
            super.onPostExecute(result);
            if (mDialog.isShowing())
                mDialog.dismiss();
            //TODO.LoginDone(result)
        }

        /**
         * @param value
         * @return
         * @throws UnsupportedEncodingException 
         */
        private String encode(String value) throws UnsupportedEncodingException{
            return URLEncoder.encode(value, "UTF-8");
        }

        private SubscriptionService parseResult(JSONObject jsonObj) throws JSONException{
                         SubscriptionService service = new SubscriptionService();
            //Do soething
            return service;
        }

    }
}

日志

11-15 15:21:37.910: E/WindowManager(1748): Activity stalker.activity.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40ffa4e0 that was originally added here
11-15 15:21:37.910: E/WindowManager(1748): android.view.WindowLeaked: Activity stalker.activity.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40ffa4e0 that was originally added here
11-15 15:21:37.910: E/WindowManager(1748):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:344)
11-15 15:21:37.910: E/WindowManager(1748):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
11-15 15:21:37.910: E/WindowManager(1748):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
11-15 15:21:37.910: E/WindowManager(1748):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
11-15 15:21:37.910: E/WindowManager(1748):  at android.view.Window$LocalWindowManager.addView(Window.java:537)
11-15 15:21:37.910: E/WindowManager(1748):  at android.app.Dialog.show(Dialog.java:278)
11-15 15:21:37.910: E/WindowManager(1748):  at stalker.activity.LoginActivity$LoginTask.onPreExecute(LoginActivity.java:262)
11-15 15:21:37.910: E/WindowManager(1748):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561)
11-15 15:21:37.910: E/WindowManager(1748):  at android.os.AsyncTask.execute(AsyncTask.java:511)
11-15 15:21:37.910: E/WindowManager(1748):  at activity.LoginActivity.onLoginButtonClick(LoginActivity.java:126)

如您所见,AsyncTask 中没有特殊代码。你能帮我解决这个问题吗?任何帮助,将不胜感激。

谢谢。

4

3 回答 3

1

窗口泄漏的主要原因是您在退出 Activity 后尝试显示 Dialog。

因此,请确保当您调用代码的 onclick 时,无论如何您都没有完成活动。

如果需要,仅在任务的后期执行中完成活动

于 2013-11-15T04:46:07.473 回答
1

可能您需要像这样在 onPreExecute 中定义 mDialog:

mDialog = new ProgressDialog(LoginTask.this);
于 2013-11-15T04:52:31.487 回答
0

当调用对话框而不处于前台状态时,活动会泄漏一个窗口。所以为了避免这种情况,我们可以在活动的 onPause() 中停止对话框。

原因:
这是因为内存泄漏发生,因为垃圾收集器无法释放分配给活动的内存,因为对话框仍然附加到它。因此 androidRuntime 抛出此错误“窗口泄漏”。

在您的情况下:将mDialog
声明为全局变量并在 onPause 中将其杀死:

    @Override
    protected void onPause() {
      if(progressDialog != null)
        progressDialog.dismiss();
      super.onPause();
    }
于 2013-11-15T04:44:29.950 回答