Comment obtenir le résultat de OnPostExecute() pour activité principale raison AsyncTask est dans une classe à part?
J'ai deux classes. Mon Activité principale et celle qui s'étend de la AsyncTask
, Maintenant, dans mon Activité principale, j'ai besoin d'obtenir le résultat de la OnPostExecute()
dans le AsyncTask
. Comment puis-je transmettre ou obtenir le résultat de mon Activité principale?
Voici un exemple de codes.
Mon Activité principale.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
C'est la classe AsyncTask
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
- Vous pouvez créer une interface comme HelmiB expliqué ou vous pouvez créer une diffusion locale du récepteur, Vous pouvez voir l'exemple de la diffusion reciver mise en œuvre ici wiki.workassis.com/android-local-broadcast-receiver
- Pourquoi ne pas utiliser pattern observer?
Vous devez vous connecter pour publier un commentaire.
Facile:
Créer
interface
classe, oùString output
est facultative, ou peut-être ce que les variables que vous souhaitez retourner.Aller à votre
AsyncTask
classe, et de déclarer l'interfaceAsyncResponse
comme un champ :Dans votre Activité principale que vous devez
implements
interfaceAsyncResponse
.Mise à JOUR
Je ne connaissais pas ce est un favori de beaucoup d'entre vous. Voici donc la simple et pratique façon d'utiliser
interface
.toujours en utilisant le même
interface
. Pour info, vous pouvez combiner ce dansAsyncTask
classe.dans
AsyncTask
classe :le faire dans votre
Activity
classeOu, la mise en œuvre de l'interface sur la reprise de l'Activité
Comme vous pouvez le voir 2 solutions ci-dessus, la première et la troisième, elle doit créer de la méthode
processFinish
, l'autre, la méthode est à l'intérieur de l'appelant paramètre. La troisième est plus soigné car il n'est pas imbriquée classe anonyme. Espérons que cela aideAstuce: Changement
String output
,String response
, etString result
à différents types de correspondance afin d'obtenir différents objets.interface
. j'ai oublié de le mettre délégué du bien :). avez ajoutés dansonCreate
.AsyncTask
classeAsyncTask
classe. dans ce cas, votreAasyncTask
. j'ai édité ma réponse en fonction de votre classe que vous avez posté.new MyTask().execute().get()
un. Toute suggestion sera apprécié.LiveData<...>
membre et l'ajout d'un observateur d'observer les modifications des données?Il ya quelques options:
Nest la
AsyncTask
classe à l'intérieur de votreActivity
classe. En supposant que vous n'utilisez pas la même tâche dans de multiples activités, c'est le moyen le plus facile. Tout votre code reste le même, il suffit de déplacer la tâche existante de la classe à une classe imbriquée à l'intérieur de votre activité de la classe.Créer un constructeur personnalisé pour votre
AsyncTask
qui prend une référence à votreActivity
. Vous instancier la tâche avec quelque chose commenew MyAsyncTask(this).execute(param1, param2)
.static
? Juste à l'utiliser toutfieldOrMethod
deMyActivity
ouMyActivity.this.fieldOrMethod
si c'est dans l'ombre.MyAsyncTask
est pas un intérieur de classe.private
/protected
de haut niveau des classes n'est pas autorisé, donc je pense qu'il doit être un non-static
intérieur de la classe.J'ai senti le ci-dessous approche est très facile.
J'ai déclaré une interface pour rappel
Ensuite créé Tâche asynchrone pour répondre à tout type de demandes parallèles
Appelait alors la tâche asynchrone lorsque vous cliquez sur un bouton dans l'activité de la Classe.
Grâce
Vous pouvez essayer ce code dans votre classe Principale.
Ce qui a fonctionné pour moi, mais j'ai mis en œuvre des méthodes d'une autre manière
execute()
, voir ma réponse, j'ai ajouté de commentaire. vous pourriez vouloir vérifier mes mises à jour de réponse. espérons que cette aide.Cette réponse peut être en retard mais je tiens à mentionner quelques choses lors de votre
Activity
dépendAsyncTask
. Qui pourrait vous aider à éviter les collisions et la gestion de la mémoire. Comme déjà mentionné dans les réponses ci-dessus, aller avecinterface
, nous avons également dire rappels. Ils vont travailler en tant qu'informateur, mais jamais, jamais, jamais envoyer forte de référence deActivity
ouinterface
toujours utiliser faible de référence dans ces cas.Veuillez vous référer à la capture d'écran ci-dessous pour trouver comment qui peuvent provoquer des problèmes.
Comme vous pouvez le voir si nous avons commencé
AsyncTask
avec un forte de référence, alors il n'ya aucune garantie que notreActivity
/Fragment
sera en vie jusqu'à ce que nous obtenir les données, de sorte qu'il serait préférable d'utiliserWeakReference
dans ces cas, et qui va également aider dans la gestion de la mémoire que nous ne pourrons jamais tenir la référence forte de notreActivity
alors il sera admissible pour la collecte des ordures après sa déformation.Découvrez ci-dessous l'extrait de code pour savoir comment utiliser génial WeakReference -
MyTaskInformer.java
Interface qui va fonctionner comme un informateur.MySmallAsyncTask.java
AsyncTask de faire de longues tâches en cours d'exécution, ce qui permettra d'utiliserWeakReference
.MainActivity.java
Cette classe est utilisée pour démarrer monAsyncTask
mettre en œuvreinterface
sur cette classe etoverride
cette méthode.Vous pouvez le faire en quelques lignes, de substituer onPostExecute lorsque vous appelez votre AsyncTask. Voici un exemple pour vous:
J'espère que cela vous a aidé, heureux codding 🙂
onPostExecute
méthode.dans votre Oncreate():
`
}`
Pourquoi des personnes font tant de mal.
Cela devrait être suffisant.
Ne pas mettre en œuvre la onPostExecute sur la async tâche plutôt mettre en œuvre de l'Activité:
@Override
?Vous pouvez appeler la
get()
méthode deAsyncTask
(ou la surchargeget(long, TimeUnit)
). Cette méthode va bloquer jusqu'à ce que leAsyncTask
a terminé son travail, à quel point il va vous retourner leResult
.Il serait sage de faire d'autres travaux entre le la création/démarrage de votre async tâche et l'appel de la
get
méthode, sinon vous n'êtes pas en utilisant l'async tâche de manière très efficace.Salut vous pouvez faire quelque chose comme ceci:
Créer une classe qui implémente l'AsyncTask
Ajouter dans l'Activité Principale
Vous pouvez écrire votre propre écouteur. C'est même comme HelmiB's réponse, mais paraît plus naturel:
Créer auditeur interface:
Puis rédigez votre tâche asynchrone:
Finalement mettre en place l'auditeur dans l'activité:
Et c'est comment vous pouvez appeler asyncTask:
Créer un membre statique dans votre classe d'Activité. Ensuite, attribuer la valeur au cours de la
onPostExecute
Par exemple, si le résultat de votre AsyncTask est une Chaîne de caractères, créer un public static string dans votre Activité
public static String dataFromAsyncTask;
Puis, dans la
onPostExecute
de l'AsyncTask, tout simplement faire un appel statique pour votre classe principale et d'en définir la valeur.MainActivity.dataFromAsyncTask = "result blah";
Je le faire fonctionner en utilisant le filetage et le gestionnaire de messages.
Les étapes comme suit:
Déclarer une boîte de Dialogue de progression
Créer une fonction pour fermer la boîte de dialogue lorsque l'opération est terminée.
Code votre les détails de l'Exécution:
Vous devez utiliser "protocoles" de déléguer ou de fournir des données à l'
AsynTask
.Les délégués et les Sources de Données
Un délégué est un objet qui agit au nom de, ou en coordination avec d', un autre objet de rencontres d'un événement dans un programme. (Apple définition)
protocoles sont des interfaces qui définissent des méthodes de déléguer certains comportements.
Voici un exemple complet!!!
essayez ceci:
Et exemple d'utilisation:
Probablement aller à la mer un peu, mais j'ai fourni les rappels pour le code d'exécution et les résultats. évidemment, pour la sécurité des threads, vous voulez faire attention à ce que vous avez accès dans l'exécution de votre fonction de rappel.
L'AsyncTask mise en œuvre:
Un rappel:
Et enfin l'exécution de la tâche asynchrone: