web-dev-qa-db-fra.com

Valeur de retour AsyncTask

Mon Android se connecte à mon site Web pour récupérer et télécharger des informations, donc j'utilise un fil AsyncTask.

Dans un cas, j'ai besoin de mon thread pour renvoyer une valeur vraie ou fausse à mon thread principal.

Existe-t-il un moyen d'obtenir cette valeur de retour à partir d'une fonction d'exécution AsyncTask?

Quand je fais ce qui suit:

Toast.makeText(Locate.this, "Testing : "+locationUpdate.execute(location), Toast.LENGTH_LONG).show();

Je reçois juste beaucoup de charabia.

Je pense que ce dont j'ai besoin est un moyen de suspendre le thread principal jusqu'à ce que le deuxième thread se termine. Le deuxième thread appelle une fonction dans le thread principal pour définir ma valeur de retour. Ainsi, lorsque le deuxième thread se termine, le thread principal peut annuler la pause et accéder à la valeur de retour définie par le deuxième fil Si cette logique est saine, veuillez proposer des suggestions ... merci!

28
sisko

Vous pouvez utiliser la méthode AsyncTask get () pour cela. Il attend si nécessaire la fin du calcul, puis récupère son résultat:

Toast.makeText(Locate.this, "Testing : " + locationUpdate.execute(location).get(), Toast.LENGTH_LONG).show();

Mais assurez-vous de ne pas bloquer le thread principal pendant une longue période, car cela entraînerait une interface utilisateur qui ne répond plus et ANR .

[~ # ~] mise à jour [~ # ~]
J'ai manqué le point que la question portait sur le téléchargement/téléchargement asynchrone Web . L'opération Web/réseau doit être considérée comme longue et donc l'approche "suspendre le thread d'interface utilisateur et attendre la fin du téléchargement" est toujours une erreur. Utilisez la méthode habituelle de publication des résultats à la place (par exemple: AsyncTask.onPostExecute, Service + sendBroadcast, bibliothèques comme Volley, RoboSpice, DataDroid, etc.).

40
Idolon

Le gestionnaire est la meilleure façon de le faire dans la méthode onPostExcecute() simplement faire

@Override
    protected void onPostExecute(Boolean bool) {
        super.onPostExecute(bool);
           Message msg=new Message();
            msg.obj=bool;
            mHandler.sendMessage(msg);
        }
    }

et votre gestionnaire de messages sera

mHandler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
        bool i=(String)msg.obj;
    }
 };
4
Sunil Pandey
public class RunWebScript {
String mString;
public RunWebScript(String url){
    try {   
        URL updateURL = new URL(url);  
        URLConnection conn = updateURL.openConnection(); 
        // now read the items returned...
        InputStream is = conn.getInputStream();  
        BufferedInputStream bis = new BufferedInputStream(is);  
        ByteArrayBuffer baf = new ByteArrayBuffer(50);  
        int current = 0;  
        while((current = bis.read()) != -1){  
            baf.append((byte)current);  
        }   
        String s = new String(baf.toByteArray());
         mString = s;
    } catch (Exception e) {  
        Log.e("ANDRO_ASYNC", "exception in callWebPage",e); 
        mString = "error";
    }
}
public String getVal(){
    return mString;
}   

}

ceci est exécuté comme ... (montrant la fin d'une méthode dans la classe appelante

        asyncWebCall (url1,CONSTANT);
}
private void asyncWebCall(String url,int actionPostExecute){
    new WebCall().execute(url,String.format("%d",actionPostExecute));
}   

La partie Async de l'entreprise est ... Notez la déclaration de cas dans onPostExecute, c'est la clé pour obtenir à nouveau la valeur retournée dans votre programme. Notez que l'appel new WebCall (). Execute (url, String.format ("% d", actionPostExecute)); est la dernière chose faite dans un thread, aucune autre instruction ne peut être exécutée, le contrôle retourne via onPostExecute.

class WebCall extends AsyncTask<String, String, String>{
    int chooser = -1;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
    @Override   
    protected String doInBackground(String... params) {
        try {
            chooser = Integer.parseInt(params[1]);
        } catch(NumberFormatException nfe) {
            Log.d("ANDRO_ASYNC",String.format("asyncReturn() mString numberformatexception = %s",params[1]));
            chooser = 0;
        }
        return(new RunWebScript(params[0])).getVal();           
    }
    protected void onProgressUpdate(String... progress) {       
    }
    @Override
    protected void onPostExecute(String gotFromDoInBkgnd) {
        Log.d("ANDRO_ASYNC",String.format("chooser = %s",chooser));
        switch (chooser){
        case CONSTANT:
            printStringx(gotFromDoInBkgnd);
            asyncWebCall(url2,5); 
            break;
        case 0:
            Log.d("ANDRO_ASYNC",String.format("case 0 = %s",gotFromDoInBkgnd));
            break;
        case 5:
            Log.d("ANDRO_ASYNC",String.format("case 5 = %s",gotFromDoInBkgnd));
            asyncWebCall(url3,7);

            break;

        default:
            Log.d("ANDRO_ASYNC",String.format("man we got problems = %s",gotFromDoInBkgnd));
            break;
        }
    }

} // fin de classe

1
user462990

Voici un exemple complet du problème du retour des valeurs d'une tâche asynchrone. Il peut arriver que de nombreuses tâches soient effectuées l'une après l'autre de manière asynchrone.

Les bases. 1. obtenez une valeur de retour d'une classe.

public class Snippet {
int computVal;
public Snippet(){
    computVal = 17*32; 
}
public int getVal(){
    return computVal;
}   

}

cela s'appelle comme ...

int hooray = (new Snippet()).getVal();
0
user462990