Autore Topic: JsonParser - Problema con Async Task e gestione risposta  (Letto 501 volte)

Offline Raffyna

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc wildfire
  • Sistema operativo:
    seven
JsonParser - Problema con Async Task e gestione risposta
« il: 18 Settembre 2015, 09:43:37 CEST »
0
Buongiorno, ho sviluppato un'applicazione che consente di effettuare N diverse richieste ad un server ed ottenere, quindi, N diverse risposte; sottolineo che le richieste vengono eseguite una alla volta a seconda delle scelte dell'utente, per esempio  richiesta dati utente, richiesta dei dati di tutti dli utenti, richiesta degli utenti nati in un certo anno...

Per fare le richieste al server ho implementato l'usuale classe JSONParser :
Codice (Java): [Seleziona]
 class AddStringTask extends AsyncTask<String, Void, JSONObject>
    {
                private ProgressDialog pDialog;
        private Context _ctx;
        private FragmentManager _fm;

        public AddStringTask(Context ctx, FragmentManager fm){
             _ctx=ctx;
            _fm=fm;

    }
                @Override
                protected void onPreExecute() {

            // Showing progress dialog
            pDialog = new ProgressDialog(_ctx);
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();
                }

        @Override
        protected void onPostExecute(JSONObject js) {

            if (pDialog.isShowing() & js!=null)
                pDialog.dismiss();

            //Scrivo la variabile JSON
            SingletonClass.getSingletonIstance();
            SingletonClass.setJson(js);

            Toast.makeText(_ctx, "Tost", Toast.LENGTH_SHORT).show();
//
//            Fragment fragment = new Dipendenti("Lista");
//            _fm.beginTransaction().replace(R.id.frame_container, fragment).commit();
        }

       @Override
        protected JSONObject doInBackground(String... params) {
                List<NameValuePair> lista = new ArrayList<NameValuePair>();

                lista.add(new BasicNameValuePair("json", params[0]));
                json = jsonParser.getJSONFromUrl("http://www.dmcc.it/reply/getData.php/", lista );
   
            long startTime = System.currentTimeMillis();
            long timeout=5000;
            while ( (System.currentTimeMillis()-startTime)<timeout && SingletonClass.getJson() == null );

            return (json);
        }
    }

L'asyncTask viene istanziato ogni qualvolta si fa una richiesta al server come ad esempio :

Codice (Java): [Seleziona]
  /**
     * User Request : include tutte le richieste utente : login, registrazione, modifica, cancellazione
     */

    public void userRequest(FragmentManager fm, Context ctx,String type, String active, String email, String password, String nome, String cognome, String matr, String phone, String id, String admin) throws Exception {

        SingletonClass.setJson(null);
        Log.e("Edit","esit user request, ID ==> "+id);
        //Dichiarazione variabili
        JSONObject internalJson = new JSONObject();

        JSONObject jsonSended = new JSONObject();

        if (type.equals("login"))
        {
            //Composizione del file di Json da inviare al server

            internalJson.put("email", email);

            internalJson.put("pwd", password);

            jsonSended.put("tag", "login");

            jsonSended.put("user", internalJson);


        } else if (type.equals("insert") || type.equals("edit")) {

            jsonSended.put("tag", "user");

            internalJson.put("name", nome);

            internalJson.put("surname", cognome);

            internalJson.put("matr", matr);

            internalJson.put("email", email);

            internalJson.put("phone", phone);

            internalJson.put("active", active);

            if (type.equals("edit"))
                jsonSended.put("id", id);
            else

                internalJson.put("pwd", password);

            internalJson.put("admin", admin);

            jsonSended.put("type", type);

            jsonSended.put("user", internalJson);

        } else if (type.equals("delete")) {

            jsonSended.put("tag", "user");

            jsonSended.put("type", type);

            jsonSended.put("id", id);


        } else if (type.equals("list")) {

            jsonSended.put("tag", "user");

            jsonSended.put("type", type);

        } else if (type.equals("show")) { //show e list stono elasborate insieme; la differenza è che lista ha un vettore di M utenti mentre show solo un utente

            jsonSended.put("tag", "user");

            jsonSended.put("type", type);

            jsonSended.put("id", id);

        }

   
        //Invio richiesta al server
        AddStringTask connection = new AddStringTask(ctx,fm);
        connection.execute(jsonSended.toString());

Tale metodo viene attivato da un determinato fragment :
Codice (Java): [Seleziona]
public class Dipendenti extends Fragment {
    UserFunctions uf;
    private android.app.Fragment fragment = null;

    ArrayList<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;

    ExpandableListAdapter listAdapter;
    ExpandableListView ListView;

    String _tag; //identifica il campo scelto dal sottomenu

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate( R.layout.dipendenti, container, false);


        ListView = (ExpandableListView) rootView.findViewById(R.id.listViewDipendenti);

        // preparing list data
        queryResult();

        setUpDrawer();


        return rootView;

    }


    //Costruttore
    public Dipendenti(String tag) {
        _tag=tag;
        uf= new UserFunctions();
    }

    public void queryResult() {

        if (_tag.equals("Lista")) {
            //Lista Dipendenti
            try {
                /**{
                 *  tag : user,
                 *  type : list
                 *  }
                 * */

                uf.userRequest(getFragmentManager(),getActivity(),"list", null, null, null, null, null, null, null, null, null);



            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (_tag.equals("Viaggi")) {
        } else {//Statistiche
        }
    }


    public void metodoProva(){
        //Decodifica della risposta dal server
        uf.userDecode("list", getActivity());


        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        List<String> temp = new ArrayList<>();
        temp.add("Dati Utente");
        temp.add("Visualizza Viaggi");
        temp.add("Visualizza Assegnazioni");
        temp.add("Visualizza Statistiche");

        //Gli elementi vengono salvati in UserNode presente nel singleton
        int size = SingletonClass.getUserNode().size();

        Log.e("Size", "Size ==> " + size);
        //analizzo i singoli nodi utente
        for (int i = 0; i < size; i++) {
            listDataHeader.add(SingletonClass.getUserNode().get(i).getName() + " " + SingletonClass.getUserNode().get(i).getSurname() + " " + SingletonClass.getUserNode().get(i).getMatr());
            listDataChild.put(listDataHeader.get(i), temp); // Header, Child data
        }

        listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild, "dipendenti");
        // setting list adapter
        ListView.setAdapter(listAdapter);

    }

    private void setUpDrawer() {


        ListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {


                        switch (childPosition) {
                            case 0: //Dati Utente
                                fragment = new Dipendenti_item(groupPosition);

                                break;
                            case 1://Modifica Utente
                                fragment = new Veicolo();
                                break;
                            case 2: // Viaggi Utente
                                fragment = new Veicolo();

                                break;
                            case 3: //Lista Assegnazioni
                                fragment = new Veicolo();

                                break;


                            default:
                                break;
                        }


                getFragmentManager().beginTransaction().replace(R.id.frame_container, fragment).commit();
                ListView.setItemChecked(childPosition, true);
                return false;
            }
        });
    }

}


Il problema è che quando ottengo la risposta dal server e quindi ho il JSON di risposta dal server vorrei mostrare i risultati a video.
Al momento l'unico metodo che ho trovato è mettere un While(Json == null); subito dopo la richiesta al server e subito dopo richiamare la funzione di decodifica :
Codice (Java): [Seleziona]
.....
   //Invio richiesta al server
  AddStringTask connection = new AddStringTask(ctx,fm);
  connection.execute(jsonSended.toString());

  //Aspetto che il server risponda
  while ( (System.currentTimeMillis()-startTime)<timeout && SingletonClass.getJson() == null );

 //Decodifico i dati e li mostro a video
 userDecode(String type, Context ctx)
Il problema è che il while di attesa blocca l'applicazione fino a quando o non ho una risposta dal server o è finito il time-out-

Come potrei ovviare a questo problema?
Grazie in anticipo per l'aiuto.

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:JsonParser - Problema con Async Task e gestione risposta
« Risposta #1 il: 18 Settembre 2015, 09:54:39 CEST »
0
Codice (Java): [Seleziona]
userDecode(String type, Context ctx)se questa è l istruzione che ti visualizza i dati , ti basta metterla nel onPostExecute dell asyntask , è quello il via libera che ti dice... ho preso i dati ! e procederà quindi al mostrare i risultati, altrimenti non avrebbe senso usare thread separati , capi ?

Offline Raffyna

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc wildfire
  • Sistema operativo:
    seven
Re:JsonParser - Problema con Async Task e gestione risposta
« Risposta #2 il: 18 Settembre 2015, 10:01:37 CEST »
0
Ciao Peater,
grazie per la risposta, il problema è che nel metodo userDecode vengono "riempite" delle listview che dovrebbero essere mostrate... :(

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:JsonParser - Problema con Async Task e gestione risposta
« Risposta #3 il: 18 Settembre 2015, 10:08:42 CEST »
0
ecco perchè lo metti nel onPost ... quando sei in onPost puoi interagire con l'interfaccia , è solo quando sei nel doInProgress , che non puoi farlo , ma in onPost , nessun problema  :D puoi incombere solo in un inghippo... ovvero esegui la task che sta lavorando nel mentre l'utente impaziente , cambia activity / fragment o semplicemente mette in standby l'app , e successivamente la task che a completato il doInProgress finisce in onPost , ma a questo punto l'activity non è più attiva e li hai l'eventuale crash , x ovviare puoi implementare cosi
Codice (Java): [Seleziona]
@Override
    public void onDetach() {
        super.onDetach();
        if (connection!= null)
        connection.cancel(true);
    }
dove connection è la tua task , ciò significa che se l'utente cambia activity / fragment la task sarà cancellata e quindi niente crash  ;-)

Post unito: 18 Settembre 2015, 10:12:14 CEST
ovviamente per poter utilizzare connection on onDetach
dovrai dichiarare questa riga
Codice (Java): [Seleziona]
AddStringTask connection = new AddStringTask(ctx,fm);come variabile globale
di seguito un esempio
Codice (Java): [Seleziona]
public class Pippo extends Fragment {
AddStringTask connection;
@Ovveride
public void onCreate(......) {
connection= new AddStringTask(ctx,fm);
.........
}
@Override
    public void onDetach() {
        super.onDetach();
        if (connection!= null)
        connection.cancel(true);
    }
}

capi ?
« Ultima modifica: 18 Settembre 2015, 10:12:14 CEST da pietroconti89, Reason: Merged DoublePost »

Offline Raffyna

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc wildfire
  • Sistema operativo:
    seven
Re:JsonParser - Problema con Async Task e gestione risposta
« Risposta #4 il: 18 Settembre 2015, 10:37:29 CEST »
0

ciao pietroconti,
finalmente ho risolto. :DD
Grazie mille per il suggerimento!!!

Offline pietroconti89

  • Utente normale
  • ***
  • Post: 164
  • Respect: +19
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note 3 N9005
  • Sistema operativo:
    Windows / Mac OSX
Re:JsonParser - Problema con Async Task e gestione risposta
« Risposta #5 il: 18 Settembre 2015, 10:38:12 CEST »
0
 ;-)