简体   繁体   English

AsyncTask,HttpClient和ProgressDialog

[英]AsyncTask, HttpClient and ProgressDialog

I'm creating a AsyncTask to login user to a server. 我正在创建一个AsyncTask来将用户登录到服务器。 The login works fine, but the ProgressDialog does not show until the end of the process. 登录工作正常,但是ProgressDialog直到过程结束才显示。 As soon as the user taps the button, the UI freezes, and my dialog does not show up. 用户点击按钮后,UI就会冻结,并且我的对话框不会显示。

I appreciate any help. 我感谢任何帮助。 Here's my code. 这是我的代码。

public class MyApp extends Activity {
    private ProgressDialog dialogo = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button loginButton = (Button) findViewById(R.id.btnLogin);
        loginButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                SharedPreferences preferencias = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
                String webAddress = preferencias.getString("webAddress", "");

                if (webAddress.isEmpty()) {
                    Toast.makeText(getBaseContext(), "Please, configure a Web Address.", Toast.LENGTH_LONG).show();
                } else {
                    EditText edtUsername = (EditText) findViewById(R.id.edtUsername);
                    EditText edtPassword = (EditText) findViewById(R.id.edtPassword);

                    HashMap<String, String> parametros = new HashMap<String, String>();
                    parametros.put("username", edtUsername.getText().toString());
                    parametros.put("password", edtPassword.getText().toString());

                    Requisicao requisicao = new Requisicao(parametros);
                    AsyncTask<String, Void, String> resposta = requisicao.execute(webAddress + "/login");

                    try {
                        Toast.makeText(getBaseContext(), resposta.get(), Toast.LENGTH_LONG).show();
                    } catch (InterruptedException e) {
                        Toast.makeText(getBaseContext(), "InterruptedException (login)", Toast.LENGTH_LONG).show();
                    } catch (ExecutionException e) {
                        Toast.makeText(getBaseContext(), "ExecutionException (login)", Toast.LENGTH_LONG).show();
                    }
                }
            }
        });

        ImageView engrenagem = (ImageView) findViewById(R.id.imgEngrenagem);
        engrenagem.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                Intent preferenciasActivity = new Intent(getBaseContext(), Preferencias.class);
                startActivity(preferenciasActivity);
            }
        });
    }



    public class Requisicao extends AsyncTask<String, Void, String> {
        private final HttpClient clienteHttp = new DefaultHttpClient();
        private String resposta;
        private HashMap<String, String> parametros = null;

        public Requisicao(HashMap<String, String> params) {
            parametros = params;
        }

        @Override
        protected void onPreExecute() {
            dialogo = new ProgressDialog(MyApp.this);
            dialogo.setMessage("Aguarde...");
            dialogo.setTitle("Comunicando com o servidor");
            dialogo.setIndeterminate(true);
            dialogo.setCancelable(false);
            dialogo.show();
        }

        @Override
        protected String doInBackground(String... urls) {
            byte[] resultado = null;
                HttpPost post = new HttpPost(urls[0]);
            try {
                ArrayList<NameValuePair> paresNomeValor = new ArrayList<NameValuePair>();
                Iterator<String> iterator = parametros.keySet().iterator();
                while (iterator.hasNext()) {
                    String chave = iterator.next();
                    paresNomeValor.add(new BasicNameValuePair(chave, parametros.get(chave)));
                }

                post.setEntity(new UrlEncodedFormEntity(paresNomeValor, "UTF-8"));

                HttpResponse respostaRequisicao = clienteHttp.execute(post);
                StatusLine statusRequisicao = respostaRequisicao.getStatusLine();
                if (statusRequisicao.getStatusCode() == HttpURLConnection.HTTP_OK) {
                    resultado = EntityUtils.toByteArray(respostaRequisicao.getEntity());
                    resposta = new String(resultado, "UTF-8");
                }
            } catch (UnsupportedEncodingException e) {
            } catch (Exception e) {
            }
            return resposta;
        }

        @Override
        protected void onPostExecute(String param) {
            dialogo.dismiss();
        }
    }
}

Try to comment out resposta.get() call in the button listener. 尝试在按钮侦听器中注释掉resposta.get()调用。 I guess it just blocks the main UI thread untill the task is finished. 我猜它只是阻塞了主UI线程,直到任务完成。

Couple things. 几件事。 First of all, don't make an instance for ASyncClass because you can only ever call it once, as per the android documentation. 首先,不要为ASyncClass创建实例,因为根据android文档,您只能调用一次。 So execute like this: new Requisicao().execute(webAddress + "/login"); 这样执行: new Requisicao().execute(webAddress + "/login");

Also, instead of calling requisicao.get() , which will, again according to documentation "Waits if necessary for the computation to complete, and then retrieves its result" (also known as blocking), from within your async class add an override: 另外,不要调用requisicao.get() ,这将再次根据文档“等待以完成计算,然后检索其结果”(也称为阻塞),从您的异步类中添加重写:

protected void onProgressUpdate(Long... progress) {
    CallBack(progress[0]); // for example
}

Where CallBack is a function in your UI thread which will handle processing your progress long, or string, or whatever else you want to throw back. 其中CallBack是UI线程中的一个函数,它将长时间处理进程,字符串,或其他任何您想回退的进程。 Mind you, your ASync class will have to be defined within the UI class instead of separately. 提醒您,您的ASync类将必须在UI类中定义,而不是单独定义。

move your 移动你的

  private ProgressDialog dialogo = null;

into the AsyncTask's fields as you did it with HTTPClient because you don't seem to use it anywhere and try to create your dialog in the constructor 就像使用HTTPClient一样进入AsyncTask的字段,因为您似乎没有在任何地方使用它并尝试在构造函数中创建对话框

public Requisicao(HashMap<String, String> params) {
            parametros = params;
          dialogo = new ProgressDialog(MyApp.this);
        }

in postExecute 在postExecute中

 if (dialogo .isShowing()) {
                dialogo .dismiss();
 }

hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM