执行 ASyncTask 时加载 ProgressBar

Posted

技术标签:

【中文标题】执行 ASyncTask 时加载 ProgressBar【英文标题】:Load ProgressBar while executing ASyncTask 【发布时间】:2015-09-20 13:06:50 【问题描述】:

我正在完成一个应用程序,现在我想添加一个进度条或类似 Material Design 加载圈的东西。 我将在用户登录时使用它。LoginActivity 的工作原理基本上是这样的:当用户点击确定按钮时,ASyncTask 从我的 API 获取一些数据。我想要的是在 ASyncTask 对我的 API 进行查询并接收数据时显示一个进度条。 我尝试了一些库和一些教程,但没有得到任何结果。这是我的 LoginActivity:

package com.tumta.henrique.teste.view;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.tumta.henrique.teste.R;
import com.tumta.henrique.teste.model.ConsultaLogin;
import com.tumta.henrique.teste.util.Connectivity;

import java.util.List;

public class LoginActivity extends ActionBarActivity implements ConsultaLogin.ConsultaConcluidaLoginListener 

    EditText txtUsuario, txtSenha;
    ActionBar actionbar;
    Button btnOk, btnCancelar;
    private AlertDialog alerta;
    String login, senha;
    Connectivity conn = new Connectivity();

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        if (Build.VERSION.SDK_INT >= 21) 
            Window window = this.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(this.getResources().getColor(R.color.azul_nav));
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        txtUsuario = (EditText) findViewById(R.id.edit_usuario);
        txtSenha = (EditText) findViewById(R.id.edit_senha);
        txtUsuario.setOnEditorActionListener(new TextView.OnEditorActionListener() 
            public boolean onEditorAction(TextView v, int actionId,
                                          KeyEvent event) 
                if (actionId == EditorInfo.IME_ACTION_GO) 
                    txtSenha.requestFocus();
                    return true;
                
                return false;
            
        );
        txtSenha.setOnEditorActionListener(new TextView.OnEditorActionListener() 
            public boolean onEditorAction(TextView v, int actionId,
                                          KeyEvent event) 
                if (actionId == EditorInfo.IME_ACTION_GO) 
                    onClickOk(v);
                    return true;
                
                return false;
            
        );
        actionbar = getSupportActionBar();
        actionbar.hide();
        btnOk = (Button) findViewById(R.id.button_ok);
        btnCancelar = (Button) findViewById(R.id.button_cancelar);
        boolean isConnected = conn.isConnected(this);
        if(isConnected == false)
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Erro");
            builder.setMessage(R.string.aviso_rede);
            builder.setPositiveButton(R.string.config, new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS), 0);
                
            );
            builder.setNegativeButton("Sair", new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    finish();
                
            );
            alerta = builder.create();
            alerta.show();
        
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_login, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    

    public void onClickOk(View view) 
        try 
            if (txtUsuario.getText().toString().equals("") || txtSenha.getText().toString().equals("")) 
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Erro");
                builder.setMessage("Preencha todos os campos!");
                builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() 
                    @Override
                    public void onClick(DialogInterface dialog, int which) 
                        login = "";
                        senha = "";
                        txtSenha.getText().clear();
                        txtUsuario.requestFocus();
                    
                );
                alerta = builder.create();
                alerta.show();
             else 
                login = txtUsuario.getText().toString();
                senha = txtSenha.getText().toString();
                ConsultaLogin.URL_STRING = "http://186.207.85.205:7001/com.henrique.rest/api/v1/status/login?usu_login="
                        + login + "&usu_senha=" + senha;
                new ConsultaLogin(this).execute();
            
         catch (Exception e) 
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Erro");
            builder.setMessage("Ocorreu um erro inesperado! \nTente novamente.");
            builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    login = "";
                    senha = "";
                    txtUsuario.getText().clear();
                    txtSenha.getText().clear();
                    txtUsuario.requestFocus();
                
            );
            alerta = builder.create();
            alerta.show();
        
    

    public void onClickCancelar(View view) 
        finish();
    

    @Override
    public void onConsultaConcluida(List<String> result) 
        if (result.isEmpty()) 
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Erro");
            builder.setMessage("Usuario ou Senha Incorreto!");
            builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    login = "";
                    senha = "";
                    txtSenha.getText().clear();
                    txtUsuario.requestFocus();
                
            );
            alerta = builder.create();
            alerta.show();
         else 
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
        
    

这是我的 ASyncTask:

package com.tumta.henrique.teste.model;

import android.os.AsyncTask;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Henrique on 16/06/2015.
 */
public class ConsultaLogin extends AsyncTask<Void, Void, List<String>> 

    private ConsultaConcluidaLoginListener listener;

    //public static String login, senha;
    public static String URL_STRING = "";


    public ConsultaLogin(ConsultaConcluidaLoginListener listener) 
        this.listener = listener;
    

    @Override
    protected List<String> doInBackground(Void... arg0) 
        try 
            String resultado = ConsultaServidor();
            return InterpretaResultado(resultado);
         catch (IOException e) 
            Log.e("Erro", "Ocorreu um erro na consulta ao servidor!", e);
         catch (JSONException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        return null;
    

    private List<String> InterpretaResultado(String resultado) throws JSONException 
        JSONObject object = new JSONObject(resultado);
        JSONArray jsonArray = object.getJSONArray("login");
        List<String> listaLogin = new ArrayList<>();
        for (int i = 0; i < jsonArray.length(); i++) 
            JSONObject jsonLogin = jsonArray.getJSONObject(i);
            if (jsonLogin.has("usu_nome")) 
                String nome = jsonLogin.getString("usu_nome");
                listaLogin.add(i, nome);
             else listaLogin.clear();
        
        return listaLogin;
    

    private String ConsultaServidor() throws IOException 
        InputStream is = null;

        try 
            URL url = new URL(URL_STRING);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            conn.getResponseCode();

            is = conn.getInputStream();

            Reader reader = null;
            reader = new InputStreamReader(is);
            char[] buffer = new char[2048];
            reader.read(buffer);
            return new String(buffer);
         finally 
            if (is != null) 
                is.close();
            
        
    

    @Override
    protected void onPostExecute(List<String> result) 
        super.onPostExecute(result);

    

    public interface ConsultaConcluidaLoginListener 
        void onConsultaConcluida(List<String> result);
    

如果您需要更多详细信息,请询问。

【问题讨论】:

AsyncTask 有一个很酷的名为 publishProgress 的方法,可用于在执行时更新 UI。对于您的需求来说,这可能有点矫枉过正,但它仍然很酷。 developer.android.com/reference/android/os/… 【参考方案1】:

将进度条添加到您的布局中(不确定),并在您初始化异步任务时打开可见性。在异步回调中,关闭可见性。

根据要求:

login = txtUsuario.getText().toString();
senha = txtSenha.getText().toString();
yourProgressBar.setVisibility(View.VISIBLE);
ConsultaLogin.URL_STRING = "http://186.207.85.205:7001/com.henrique.rest/api/v1/status/login?usu_login=" + login + "&usu_senha=" + senha;
new ConsultaLogin(this).execute();

结果:

@Override
public void onConsultaConcluida(List<String> result) 
    if (result.isEmpty()) 
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Erro");
        builder.setMessage("Usuario ou Senha Incorreto!");
        builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialog, int which) 
                login = "";
                senha = "";
                txtSenha.getText().clear();
                txtUsuario.requestFocus();
            
        );
        alerta = builder.create();
        alerta.show();
     else 
        yourProgressBar.setVisibility(View.GONE);
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    

【讨论】:

我在哪里增加进度条的值?在doOnBackGround()? 你会使用一个不确定的进度条,这意味着它会一直旋转直到收到回调。 更多关于ProgressBar - “在不确定模式下,进度条显示一个没有进度指示的循环动画。此模式由应用程序在任务长度未知时使用。不确定进度bar 可以是旋转的***,也可以是单杠。” 其实成功了,我实现错了,我会做更多的测试,如果我有任何问题我会告诉你..

以上是关于执行 ASyncTask 时加载 ProgressBar的主要内容,如果未能解决你的问题,请参考以下文章

02Android--AsyncTask原理解析

执行 ASyncTask 时加载 ProgressBar

安卓学习笔记之AsyncTask机制浅析

android AsyncTask 怎么返回值给UI线程

AsyncTask粗糙讲解

AsyncTask粗糙讲解