Autore Topic: AsyncTask richiamato ogni volta che una activity viene chiusa  (Letto 408 volte)

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
AsyncTask richiamato ogni volta che una activity viene chiusa
« il: 30 Maggio 2014, 00:10:25 CEST »
0
Sto impazzendo.
Nella mia app ho una activity principale e 3 activity secondarie accessibile tramite menu su action bar.
Nella activity principale attraverso onActivityResult controllo i risultati di una delle 3 activity secondarie quindi uso AsyncTask per scaricare dei dati JSON da un server se i valori ottenuti da onActivityResult sono di un certo tipo.
Fin qui tutto bene.
Il problema e che apro un'altra delle activity secondarie quindi torno "indietro" nell'activity principale noto da logcat che sebbene onActivityResult non sia evocato, dato che uso startActivity invece di startActivityForResult, il codice presente nell'AsyncTask viene eseguito generando un errore.
Non riesco a capire il motivo AsyncTask viene richiamato solo in onActivityResult, perchè quando l'activity principale è richiamata il codice dell'AsyncTask viene eseguito?

Una volta terminato la sua funzione di download dei dati JSON, l'AsyncTask non dovrebbe smettere di esistere?

Grazie

Offline LinkOut

  • Utente normale
  • ***
  • Post: 271
  • Respect: +38
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:AsyncTask richiamato ogni volta che una activity viene chiusa
« Risposta #1 il: 30 Maggio 2014, 09:09:18 CEST »
0
Non ho ben capito il problema, potresti postare lo stack di errore?

Se tu hai un'activity principale, la quale deve interpretare l'"onActivityResult" delle altre activity, allora onActivityResult deve essere presente nelle 3 activity delle quali vuoi alcuni risultati, questa callback viene eseguita solo dopo aver chiuso l'activity secondaria con finish();

L'esempio che c'è su developer.adroid è molto chiaro:"La tua app fa partire la fotocamera e preleva la foto fatta"

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
Re:AsyncTask richiamato ogni volta che una activity viene chiusa
« Risposta #2 il: 30 Maggio 2014, 10:41:34 CEST »
0
Cerco di spiegarmi meglio riportando anche un pò di codice.
Come detto ho un activity principale  e 3 activity secondarie che vengono richiamate dal menu dell'activity principale. Io ho bisogno solo solo di interpretare i risultati di 2 activity secondarie la terza infatti è solo relativa ai crediti quindi non fornisce risultati.
Delle altre 2 activity solo una fornisce risultati tali da richiamare eventualmente (dipende dai risultati) il mio AsyncTask che durante l'esecuzione richiama un indirizzo web, aspetta i risultati e li interpreta tramite JSONObject.
Il tutto è abbastanza semplice anche per me che non ho mai programmato in Java.

Questo è il codice con il quale avvio le activity secondarie da quella principale:

Codice (Java): [Seleziona]
    private void openSearchActivity() {
        Intent intent = new Intent(this, SearchActivity.class);
        startActivityForResult(intent, 1);
    }

    private void openSettingsActivity() {
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivityForResult(intent, 2);
    }

    private void openCreditsActivity() {
        Intent intent = new Intent(this, CreditsActivity.class);
        startActivity(intent);
    }

mentre questo è il codice che interpreta i risultati delle activity secondarie:

Codice (Java): [Seleziona]
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == RESULT_OK){
                String url = "http://www.martinzone.it/topotaf/getpflist_mobile.php";

                String query = "cmd=c&rad=" + Integer.toString(data.getExtras().getInt("EXTRA_RAGGIO")) + "&pnt=20&lat=" + Float.toString(data.getExtras().getFloat("EXTRA_LATITUDINE")) + "&lon=" + Float.toString(data.getExtras().getFloat("EXTRA_LONGITUDINE"));
                url = url + "?" + query;

                httptask = new HttpGetTask();
                httptask.execute(url);
            }

            if (resultCode == RESULT_CANCELED) {
                //Write your code if there's no result
            }
        } else if (requestCode == 2) {
            sharedSettings = PreferenceManager.getDefaultSharedPreferences(MapsActivity.this);
            Boolean mostraPosizione = sharedSettings.getBoolean("settingMostraPosizione", true);

            if (mostraPosizione) {
                MoveUserMarker();
            } else {
                RemoveUserMarker();
            }
        }

    }


infine riporto il codice AsyncTask:

Codice (Java): [Seleziona]
    private class HttpGetTask extends AsyncTask<String,String,String> {

        ProgressDialog pDialog;
        @Override
        protected void onPreExecute(){
            pDialog = new ProgressDialog(MapsActivity.this);
            pDialog.setCancelable(false);
            pDialog.setMessage("Ricerca in corso...");
            pDialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            MapPointsList.clear();
            MapPolylinesList.clear();
            clientResult = null;
            clientCodeResult = "0";
            clientLatitudeResult = 0.0;
            clientLongitudeResult = 0.0;

            if(isCancelled()){
                return "";
            }

            // interrogazione del web service
            try {
                // creo la richiesta URI di tipo GET
                URI uri;
                uri = new URI(params[0]);
                HttpUriRequest get = new HttpGet(uri);

                // istanzio il client HTTP
                client = new DefaultHttpClient();

                // istanzio il gestore automatico di risposte HTTP
                ResponseHandler<String> responseHandler = new BasicResponseHandler();

                // eseguo la richiesta
                clientResult = client.execute(get,responseHandler);

            } catch (HttpResponseException e) {
                // gestisce le risposte diverse da HTTP code 200
                Log.w("MIAPPICAZIONE","HTTP Response Exception : "+e.toString());
            } catch (Exception e) {
                Log.w("MIAPPICAZIONE","Error : "+e.toString());
            } finally {
                if (client != null) client.getConnectionManager().shutdown();
            }

            if(isCancelled()){
                return "";
            }

            // JSON parsing
            if (clientResult!=null) try {
                JSONObject jObject = new JSONObject(clientResult);
                clientCodeResult = jObject.getString("responseStatus");
                clientLatitudeResult = jObject.getDouble("responseCenterLatitude");
                clientLongitudeResult = jObject.getDouble("responseCenterLongitude");

                JSONArray JOresponsePoints  = jObject.getJSONArray("point");

                for(int i = 0; i<JOresponsePoints.length(); i++) {
                    JSONObject JOresponsePoint = JOresponsePoints.getJSONObject(i);
                    MapPoint mapPoint = new MapPoint(JOresponsePoint.getString("name"), JOresponsePoint.getDouble("latitude"), JOresponsePoint.getDouble("longitude"),JOresponsePoint.getString("status"), JOresponsePoint.getString("kind"));

                    MapPointsList.add(mapPoint);
                }

            } catch (JSONException e) {
                Log.w("MIAPPICAZIONE","JSON Exception : "+e.toString());
            }

            return clientResult;
        }
        }

Il mio codice sembra funzionare, il problema è che quando apro una activity secondaria che non sia SearchActivity ovvero quella che poi richiama AsyncTask ottengo un messaggio di errore tramite logcat che sembra essere sempre legato al codice dell'AsyncTask e non capisco perchè. Nell'applicazione non compaiono errori ma l'array MapPointsList viene svuotato cosa che accade appunto nell'AsyncTask.

Questo è l'errore riportato da logcat:

Codice (Java): [Seleziona]
05-30 10:37:23.183    4379-4379/com.miapplicazione.app E/WindowManager? android.view.WindowLeaked: Activity com.miapplicazione.app.MapsActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41b70128 G.E..... R.....ID 0,0-456,144} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at com.miapplicazione.app.MapsActivity$HttpGetTask.onPreExecute(MapsActivity.java:766)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
            at android.os.AsyncTask.execute(AsyncTask.java:535)
            at com.miapplicazione.app.MapsActivity.onActivityResult(MapsActivity.java:698)
            at android.app.Activity.dispatchActivityResult(Activity.java:5423)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3361)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3408)
            at android.app.ActivityThread.access$1300(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

dove MapsActivity.java:698 corrisponde alla riga "httptask.execute(url);" presente in "onActivityResult" e "MapsActivity.java:766" corrisponde alla riga "pDialog.show();" presente nell'AsyncTask.

Spero possiate aiutarmi perchè sto diventando matto.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:AsyncTask richiamato ogni volta che una activity viene chiusa
« Risposta #3 il: 30 Maggio 2014, 10:56:24 CEST »
0
Una delle cause dell'eccezione android.view.WindowLeaked è la distruzione di una activity nella quale avevi aperto una dialog (show) ma non l'avevi chiusa (dismiss).

Nel codice non si vede, ma controlla che nella OnPostExecute dell'AsyncTask fai correttamente il dismiss della pdialog.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
Re:AsyncTask richiamato ogni volta che una activity viene chiusa
« Risposta #4 il: 30 Maggio 2014, 12:26:08 CEST »
0
Grazie mille. Era proprio quello il problema. Usavo solo hide() per nasconderlo.