How to make an Array created inside an AsyncTask be global?

0

In my original version I populated my spinner from an Array, placed in strings.xml

And to know which selection the user made, he used the following code

code 1

@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
    // get selected option
    String[] names = getResources().getStringArray(R.array.confirmation_memo);
    selectedName = names[position];

}

But now I get the array from a URL and for that I had to implement the AsyncTask method to get the OnLine data from the company's website.

with the following code:

code 2

    public class JSONOAsyncTask extends AsyncTask<String, Void, Boolean> implements  AdapterView.OnItemSelectedListener{

        private Spinner spinner;
        private ArrayAdapter<String> dataAdapter;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            spinner = (Spinner) findViewById( R.id.memo_confirmation_spinner );
            spinner.setOnItemSelectedListener(PostConfirmationActivity.this);
        }

            @Override
            protected Boolean doInBackground(String... urls) {
                try {
                    Log.e("****** MESSAGE ******", " Json Object  = " + JSONParser.getJSONFromUrl( URL ).get("ReportDetailTextList"));

                    List < String > categories = new ArrayList < String > ();
                    JSONArray array = (JSONArray) JSONParser.getJSONFromUrl(URL).get("ReportDetailTextList");
                    for (int i = 0; i < array.length(); i++) {
                        categories.add(array.get(i).toString());

                        // puting the first option from the URL, to be the "default memo field".
                        if(i == 0) {
                            selectedName = array.get(i).toString();
                        }

                    }
                    dataAdapter = new ArrayAdapter < String > (getBaseContext(), android.R.layout.simple_spinner_dropdown_item, categories);
                    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return false;
            }

        protected void onPostExecute(Boolean result) {
            // putting adapter in to data
            spinner.setAdapter(dataAdapter);
   }

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    }

And everything works fine , unless I can not get "code 1" to use the URL array of AsyncTask) ... and so make the choice in the spinner,

  

That is:

Inside AsyncTask, I create ARRAY on the line:

JSONArray array = (JSONArray) SONParser.getJSONFromUrl(URL).get("ReportDetailTextList");

And I would like to use this OUTPUT AsyncTask array in code

public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
    // get selected option
    String[] names = getResources().getStringArray(R.array.confirmation_memo);
    selectedName = names[position];

}


Or is there a better way to pick up the spinner's choice? following the idea of using AsyncTask?

    
asked by anonymous 31.01.2017 / 09:52

3 answers

1

A simple solution to get the value clicked on your Spinner is to create a variable in your out class PostConfirmationActivity . For example String selectedName , which is apparently already created, it will receive the value you will click or select.

Inside your JSONAsyncTask, it will declare as follows:

    private Spinner spinner;
    private ArrayAdapter<String> dataAdapter;
    private List<String> categories;

No doInBackground :

 try {
     Log.e("****** MESSAGE ******", " Json Object  = " + JSONParser.getJSONFromUrl(URL).get("ReportDetailTextList"));

     categories = new ArrayList <String> ();
     JSONArray array = (JSONArray) JSONParser.getJSONFromUrl(URL).get("ReportDetailTextList");
     for (int i = 0; i < array.length(); i++) {
         categories.add(array.get(i).toString());

         // puting the first option from the URL, to be the "default memo field".
         if (i == 0) {
             selectedName = array.get(i).toString();
         }    
     }
     dataAdapter = new ArrayAdapter < String > (getBaseContext(), android.R.layout.simple_spinner_dropdown_item, categories);
     dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

 } catch (JSONException e) {
     e.printStackTrace();
 }

If your onItemSelected :

// esse spinnerClicado você tem que declarar na sua inner class PostConfirmationActivity
// dai então você poderá usar ela em qualquer local
selectedName = categories.get(position);

// esse toast é só para mostrar para o usuário qual item ele clicou
Toast.makeText(getBaseContext(),""+categories.get(position),Toast.LENGTH_SHORT).show();
    
01.02.2017 / 03:33
4

You can adopt a slightly different strategy today, from what I saw your class JSONOAsyncTask makes the request and interprets the answer within the class itself.

This may be bad when you have to make a request and have to interpret the response differently, so I suggest you create a Listener interface, causing each class to invoke your class AsyncTask , analyze and interpret the answer differently.

Listener example :

public interface AsyncTaskCompleteListener<JSONObject> {
    public void onTaskComplete(org.json.JSONObject result) throws JSONException;
}

WebService Class

public class WebServiceTask extends AsyncTask<String, Integer, String>{

    public static final int POST_TASK = 1;
    public static final int GET_TASK = 2;
    public static final int DELETE_TASK = 3;
    public static final int PUT_TASK = 4;

    public JSONObject returnWS;

    private static final String TAG = "WebServiceTask";

    //Time out para conexão em milisegundos
    private static final int CONN_TIMEOUT = 7000;

    //Tempo de timeout em milisegundos para espera dos dados... (5 segundos é pouco e 10 é muito, escolhido 7 por ser a média)
    private static final int SOCKET_TIMEOUT = 7000;

    private int taskType = GET_TASK;
    private Context mContext = null;
    private String processMessage = "Processando...";
    private AsyncTaskCompleteListener<String> callback;
    private boolean hideProcessMessage = false;
    private String msgErro;

    private ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

    private ProgressDialog pDlg = null;

    public WebServiceTask(int taskType, Context mContext, String processMessage, AsyncTaskCompleteListener<String> cba) {
        this.taskType = taskType;
        this.mContext = mContext;
        this.processMessage = processMessage;
        this.callback = cba;
    }


    private void showProgressDialog() {
        pDlg = new ProgressDialog(mContext);
        pDlg.setMessage(processMessage);
        pDlg.setIndeterminate(true);
        pDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDlg.setCancelable(false);
        pDlg.show();
    }

    public void addParameter(String name, String value) {
        params.add(new BasicNameValuePair(name, value));
    }

    @Override
    protected void onPreExecute() {
        if(!this.hideProcessMessage)
            showProgressDialog();
    }

    protected String doInBackground(String... urls) {

        String url = urls[0];
        String result = "";

        HttpResponse response = doResponse(url);

        if (response == null) {
            onPostExecute(result);
            return result;
        } else {
            try {
                result = inputStreamToString(response.getEntity().getContent());
            } catch (IllegalStateException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            } catch (IOException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            }
        }
        return result;
    }

    @Override
    protected void onPostExecute(String response) {
        try{
           callback.onTaskComplete(new JSONObject(response));
        }catch (JSONException e){
            Log.v(TAG, "Problemas para obter resposta do servidor.");
        }
    }

    public void handleResponse(String response, Context context) {
        try {
            JSONObject jso = new JSONObject(response);
            returnWS = jso;
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    // Estabelece conexão e define timeout do socket
    private HttpParams getHttpParams() {
        HttpParams htpp = new BasicHttpParams();

        HttpConnectionParams.setConnectionTimeout(htpp, CONN_TIMEOUT);
        HttpConnectionParams.setSoTimeout(htpp, SOCKET_TIMEOUT);

        return htpp;
    }

    private HttpResponse doResponse(String url) {
        // Use our connection and data timeouts as parameters for our
        // DefaultHttpClient
        HttpClient httpclient = new DefaultHttpClient(getHttpParams());
        HttpResponse response = null;

        try {
            switch (taskType) {
                case PUT_TASK:
                    HttpPut httpPut = new HttpPut(url);
                    httpPut.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
                    response = httpclient.execute(httpPut);
                    break;

                case POST_TASK:
                    HttpPost httpPost = new HttpPost(url);
                    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
                    response = httpclient.execute(httpPost);
                    break;

                case GET_TASK:
                    HttpGet httpget = new HttpGet(url);
                    response = httpclient.execute(httpget);
                    break;

                case DELETE_TASK:
                    HttpDelete httpDelete = new HttpDelete(url);
                    response = httpclient.execute(httpDelete);
                    break;


            }
        } catch (Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
            if (!hideProcessMessage)
                pDlg.dismiss();
        }

        return response;
    }

    private String inputStreamToString(InputStream is) {

        String line = "";
        StringBuilder total = new StringBuilder();

        // Wrap a BufferedReader around the InputStream
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));

        try {
            // Read response until the end
            while ((line = rd.readLine()) != null) {
                total.append(line);
            }
        } catch (IOException e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        }

        // Return full string
        return total.toString();
    }

}

Your main class, which makes the request, will have to implement interface :

public class ActivityIncluirItemPedido implements AsyncTaskCompleteListener {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
       [...]
    }


    protected void clickBuscarDados(View view){

      WebServiceTask webServiceTask = new WebServiceTask(WebServiceTask.POST_TASK, view.getContext(), "Buscando dados do usuário", this);

      //Se houver algum parametro para filtro no back-end
      webServiceTask.addParameter("idUsuario", _idUsuario.getText().toString());

      //Endereço do WS back-end que receberá a chamada
      webServiceTask.execute(new String[]{"localhost:8080/WSLocal/UsuarioWS"});
  }


    [....]
    @Override
    public void onTaskComplete(JSONObject result) throws JSONException {
       JSONArray jsonArray = result.getJSONArray("<Chave do Json">);


    }


}

In this way, when the method calls onPostExecute , it will reference its class that implements the interface AsyncTaskCompleteListener .

You can do the following as well: 1 - Get the message from your backend and save it in an array of strings

 Array of choices
String colors[] = {"Red","Blue","White","Yellow","Black", "Green","Purple","Orange","Grey"};

// Selection of the spinner
Spinner spinner = (Spinner) findViewById(R.id.myspinner);

// Application of the Array to the Spinner
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this,   android.R.layout.simple_spinner_item, colors);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
spinner.setAdapter(spinnerArrayAdapter);
    
31.01.2017 / 11:02
0

In addition to Carlos Bridi's response, there is also an equally cool way, which is similar to firebase operation ... That is, you create an interface and receive it in the asynctask constructor, and finally, at the time of calling asynctask, you create a new object and program whatever asynctask does. Example:

public interface IResultado {

    Object processamento(); // o tipo pode ser outro também, variamento conforme a necessidade
    void resultado(Object resultado);

}

The generic asynctask

public class AsyncTaskResultado extends AsyncTask<Object, Integer, Object> {

    private IResultado results;

    public AsyncTaskResultado(IResultado results) {
        this.results = results;
    }

    @Override
    protected Object doInBackground(Object... objects) {
        return results.processamento();
    }

    @Override
    protected void onPostExecute(Object resultado) {
        results.resultado(resultado);
    }
}

Na activity ...

void minhaRequisição(){

    new AsyncTaskResultado(new IResultado() {

                @Override
                public Object processamento() {
                    // aqui voce programa o que quer que a asynctask faça...
                    // e deverá retornar um objeto
                    return "myJson"; // aqui retorna seu JSON.
                    }

                @Override
                public void resultado(Object resultado) { // o JSON vai vir pra cá
                   // aqui o que ela vai fazer após terminar... 
                   // no seu caso, preenche o spinner com o json (não esqueça de dar um cast)
                }

            }).execute();
    }

This is just an example. Use your creativity to shape it to your need. This asynctask can be used multiple times. What will change is what you program when you give a new one on it ...

    
31.01.2017 / 13:25