POST requests with Android loading icon

Asked

Viewed 100 times

0

I’m making an Android application that will make some requests to an API, I generalized these requests in a class (Requestapi), where, to use it, just create a map with the information I’ll send to the API and call in the following way:

new RequestApi(activity, url, mapa_com_as_variaveis).exec();
//o retorno dessa requisição serão um JSONObject com a resposta do servidor

This works, but I am trying to put a loading icon while the request is being performed (the user can only perform any action after the server response, ie it is a synchronous request).

package br.com.david.system.Utils;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.widget.Toast;

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

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import br.com.david.system.Database.MaquinaHelper;
import br.com.david.system.PrincipalActivity;
import br.com.david.system.R;

public class RequestApi {
    public static final String BASE_URL = "http://myapi.com.br/api/";

    private String url;
    private String json;
    private String message;
    private String request;
    private JSONObject response;
    private Activity activity;

    public RequestApi(Activity a, String url, Map<String, Object> data) {
        this.activity = a;
        this.url = url;
        setCrypt(data); //criptografo os dados que serão enviados pra API
    }

    public JSONObject exec(){

        init(); //inicio o carregamento (ícone loading)

        Log.e("JSON_SEND", json);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    //
                    URLConnection conn = new URL(url).openConnection();
                    conn.setDoOutput(true);
                    conn.setConnectTimeout(15000);
                    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

                    OutputStream os = conn.getOutputStream();
                    os.write(json.getBytes("UTF-8"));
                    os.flush();

                    InputStream in = new BufferedInputStream(conn.getInputStream());
                    request = convertStreamToString(in);

                    in.close();
                    os.close();

                    if (request != null) {

                        Log.e("RESPONSE", "response: " + request.toString());
                        try {

                            response = new JSONObject(request);
                            if (response.getInt("error_code") == 0) {

                                if (response.get("data") instanceof JSONObject) {

                                    JSONObject dataResponse = response.getJSONObject("data");
                                    if (dataResponse.has("x-auth-token")) {
                                        //verifico os tokens do cabeçalho
                                    }

                                }

                            } else {

                                message = response.getString("message");
                                Log.e("URL", "url: " + url);

                            }

                        } catch (final JSONException e) {

                            message = "Não foi possível obter a resposta do servidor";
                            Log.e("ERROR", "json_error: " + e.getMessage());
 }

                    } else {

                        message = "Não foi possível conectar-se ao servidor";

                    }

                } catch (Exception e){

                    Log.e("Exception", "err -> " + e.getMessage());

                }

            }

        });

        thread.start();
        Log.e("THREAD", "start()");
        try {

            thread.join();
            Log.e("THREAD", "end()");
            abort();
            Log.e("REPS", "Response: " + response.toString());
            return response;

        } catch (InterruptedException e) {

            e.printStackTrace();
            Log.e("THREAD", e.getMessage());
            return null;

        }

    }

    private void setCrypt(Map<String, Object> data){

        for(Map.Entry<String, Object> entry : data.entrySet()) {
            //criptografo os dados do mapa
        }

        json = new JSONObject(data).toString();
    }

    public void init(){ //open loading
        ViewGroup frameLayout = activity.findViewById(R.id.flContent);
        LayoutInflater inflater = (LayoutInflater) activity.getApplicationContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View myView = inflater.inflate(R.layout.loading, null);
        if(frameLayout != null){
            frameLayout.addView(myView);
        }
    }

    protected void abort() { //close loading
        ViewGroup group = (ViewGroup) activity.findViewById(R.id.loading);
        ((ViewManager) group.getParent()).removeView(group);
    }

    /*
     * To convert the InputStream to String we use the
     * Reader.read(char[] buffer) method. We iterate until the
     * Reader return -1 which means there's no more data to
     * read. We use the StringWriter class to produce the string.
     */
    public String convertStreamToString(InputStream is) throws IOException {
        if (is != null) {
            Writer writer = new StringWriter();

            char[] buffer = new char[1024];
            try {
                Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                int n;
                while ((n = reader.read(buffer)) != -1) {
                    writer.write(buffer, 0, n);
                }
            } finally {
                is.close();
            }
            return writer.toString();
        } else {
            return "";
        }
    }

}

I have tried SEVERAL ways to make the loading screen appear (it is an external file, R.layout.loading), among them:

  • Pure Code: An error occurred stating that I could not execute requests in the Main Thread;
  • Asynctask: The icon appeared only after the request ended (I put the code that started the icon in onPreExecute, before the Asynctask call and even in various places of the code;
  • Thread: As an example below, it works the same way with Asynctask, the icon is only displayed after the request is completed;
  • Handler.post and Handler.postDelayed: Same as Thread and Asynctask;
  • For all cases I tried to put the icon opening in runOnUIThread and with Handlers, I tried several other ways too (things I knew didn’t make any sense).

I’m out of options, can someone help me? (the loading icon is a layout with a Relativelayout - almost transparent background grabbing the entire screen - and a Progressbar, all screens have a Framelayout with ID = flContent).

1 answer

0

Calls your progressbar before performing its function

init();

new RequestApi(activity, url, mapa_com_as_variaveis).exec();

Browser other questions tagged

You are not signed in. Login or sign up in order to post.