How to make an Array created within an Asynctask be global?

Asked

Viewed 248 times

0

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

And to know which selection the user made 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 take the array of a URL and, for that, I had to implement the Asynctask method to get the data Online from the emrpesa 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’t get the "code 1", pass to use the URL array (which is created inside Asynctask)... and so make the choice in the spinner,

That is to say:

within Asynctask, create the ARRAY on the line:

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

and would like to use this OFF array from Asynctask, in the 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 if you take the choice of the spinner? following the idea of using Asynctask?

3 answers

4

You can adopt a slightly different strategy today, so I’ve seen your class JSONOAsyncTask make the request and interpret the answer within the class itself.

This can be bad at the time you have to request and have to interpret the response differently, so I suggest you create an interface Listener, making every class that invokes your class AsyncTask, analyze and interpret the response differently.

Example of Listener:

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

Class of the Webservice

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, who make the request, will have to implement the 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">);


    }


}

Thus, when the method calls onPostExecute, it will reference your class that implements the interface AsyncTaskCompleteListener.

You can do it this way too: 1 - Receive the message from your back-end 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);
  • @Camilayamamoto From what I understand, you will call your webservice, pick up values and want to put them in a Spinner, correct? If so, you need to interpret your Ws response, add in an array of strings and add "manually".

  • @Camilayamamoto I made an adjustment in the answer and I finally added an example of how to do what I mentioned above, if you have any questions, call me. Do not be discouraged!

  • For me, Java had its nod when everyone could see in practice the multiplatform, etc...when the new languages came, cross-Platform, everyone began to wonder about it...I think Java has its benefits, just like all other languages also have... Now everyone is passionate about Ionic, angular, and so it goes, every cycle, a new language of the moment..

  • 1

    Thank you Carlos! you helped me to study more! Thank you so much for the good will! We, the newbies, need more people like you... It’s hard to learn! and you guys are not charging us even more.... Useful otherwise, help and give more touches!!! That’s how we learn and have more respect for you! Are you listening to @Ack Lay ?? happy here!

  • Hello Camila, sorry, yesterday the internet operator did maintenance on the network and I could not answer you in chat. If you ever go up this project in Git, I can help you re-create and separate the concepts from the better classes... Thank you and keep moving forward ;)

  • cool! thanks!

Show 2 more comments

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 apparently is already created, which will receive the value you will click or select.

Inside your Jsonasynctask, you will declare as follows:

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

In the 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();
 }

In his case 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();
  • simple! now she’s global... faltering my.. THANKS! A LOT!

0

In addition to the response of Carlos Bridi, there is also an equally legal way, which is similar to the operation of firebase... That is, you create an interface and get it in the asynctask constructor, and finally, when you call 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);

}

A 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);
    }
}

In 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 one example. Use your creativity to shape your need. This asynctask can be used several times. What will change is what you program when you give a new one...

Browser other questions tagged

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