Une brève analyse du mécanisme de transmission des messages du gestionnaire


Introduction à cette section

Dans les deux premières sections, nous avons étudié les deux mécanismes de traitement des événements dans Android. Il n'y a que ces deux types de réponses aux événements ; Il s'agit du gestionnaire de transfert d'informations dans le composant UI de l'activité. Je pense que de nombreux amis savent que, pour des raisons de sécurité des threads, Android ne nous permet pas d'utiliser l'interface utilisateur en dehors du thread de l'interface utilisateur plusieurs fois lorsque nous actualisons l'interface ; vous devez notifier la mise à jour du composant de l'interface utilisateur via le gestionnaire ! En plus d'utiliser Handler pour effectuer les mises à jour de l'interface, vous pouvez également utiliser runOnUiThread() pour mettre à jour des bus de transaction encore plus avancés. Bien sûr, nous expliquons ici uniquement Handler, ce qu'est Handler, le processus d'exécution, les méthodes associées et son utilisation dans les sous-applications. threads et threads principaux. La différence entre Handler et plus encore !


Feuille de route d'apprentissage :

1.jpg


2. Introduction de la classe Handler :

2.jpg


3. Organigramme d'exécution du gestionnaire :

3.jpg

Analyse de l'organigramme : Noms associés

  • Thread UI  : C'est notre thread principal. Lorsque le système crée le thread UI, il initialise un objet Looper et crée également une MessageQueue qui lui est associée
  • ;
  • Handler : La fonction est d'envoyer et de traiter des informations. Si vous souhaitez que le Handler fonctionne normalement, il doit y avoir un objet Looper dans le fil de discussion actuel
  • Message<. 🎜> : Objet Message reçu et traité par Handler
  • MessageQueue : File d'attente des messages, gestion premier entré, premier sorti Message, lors de l'initialisation de l'objet Looper, une MessageQueue qui lui est associée sera créé;
  • Looper : Chaque thread ne peut avoir qu'un seul Looper, qui gère la MessageQueue et en extrait en continu les messages et les distribue au gestionnaire correspondant pour traitement !

Pour faire simple :

Lorsque notre fil de discussion enfant souhaite modifier les composants de l'interface utilisateur dans l'activité, nous pouvons créer un nouvel objet Handler, envoie des informations au thread principal via cet objet ; et les informations que nous envoyons attendront d'abord dans la MessageQueue du thread principal, seront extraites par Looper dans l'ordre premier entré, premier sorti, puis distribuées au Gestionnaire correspondant pour le traitement selon l'attribut quel de l'objet message !


4. Méthodes associées de Handler :

  • void handleMessage(Message msg) : Méthode de traitement des messages, généralement utilisée Overridden !
  • sendEmptyMessage(int quoi) : Envoyer un message vide
  • sendEmptyMessageDelayed(int quoi, long delayMillis) : Spécifier le délai Envoyer un message vide après millisecondes
  • sendMessage(Message msg) : Envoyer le message immédiatement
  • sendMessageDelayed(Message msg) : Spécifiez le délai après combien de millisecondes Envoyer message
  • final boolean hasMessage(int what) : Vérifiez si la file d'attente des messages contient un message avec l'attribut what comme valeur spécifiée Si le paramètre est (int quoi, objet Objet) : En plus de juger l'attribut quoi, vous devez également juger si l'attribut Objet est un message pour l'objet spécifié

5. Exemple d'utilisation du gestionnaire :

1) Le gestionnaire est écrit dans le thread principal

Dans le thread principal, parce que le système a initialisé un objet Looper, nous créons directement le gestionnaire s'opposer à l'envoi d'informations. Et traitez-le !

Exemple de code : Un programme simple qui change régulièrement d'image Grâce au minuteur Timer, il modifie régulièrement le contenu affiché par ImageView pour former une animation de cadre

Rendu en cours d'exécution :

4.gif

Code d'implémentation :

< ; RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id= " @+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="com.jay.example . handlerdemo1.MainActivity" >

<ImageView
android:id="@+id/imgchange"
android:layout_width="wrap_content"
android: layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />

</RelativeLayout>

MainActivity.java:

public class MainActivity extends Activity {

//Définissez l'identifiant du tableau de l'image commutée
int imgids[] = new int[]{
R.drawable.s_1, R.drawable.s_2,R.drawable.s_3,
R.drawable.s_4,R.drawable.s_5,R.drawable.s_6,
R.drawable.s_7,R.drawable.s_8
} ;
int imgstart = 0;

final Handler myHandler = new Handler()
{ Effectuer les opérations suivantes
public void handleMessage(Message msg) {
if(msg.what == 0x123)
{
imgchange.setImageResource(imgids[img start++ % 8]);
} }
}  
 } ;
setContentView(R.layout. Activity_main );
final ImageView imgchange = (ImageView) findViewById(R.id.imgchange);

//Utilisez une minuterie pour laisser le gestionnaire envoyer un message vide toutes les 200 millisecondes
new Timer( ) .schedule(new TimerTask() {                                                                                     myHandler.sendEmptyMessage(0x123);
                                   🎜>


2) Le gestionnaire est écrit dans le sous-thread

Si le gestionnaire est écrit dans le sous-thread, nous devons créer nous-mêmes un objet Looper ! Le processus de création est le suivant :

1 )

Appelez directement la méthode Looper.prepare() pour créer un objet Looper pour le thread actuel. , et son constructeur créera un MessageQueue correspondant ;

2)

Créez un objet Handler et remplacez la méthode handleMessage() Traitement des informations provenant d'autres threads !
3)

Appelez Looper.loop(). méthode pour démarrer LooperExemple d'utilisation : Entrez un nombre et, après le calcul, affichez tous les nombres premiers de cette plage via Toast Code d'implémentation : main.xml :

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"

android:orientation=" vertical ">
<EditText
android:id="@+id/etNum"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height = "wrap_content"
android:hint="Veuillez entrer la limite supérieure"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick ="cal"
android:text="Calcul"/>
</LinearLayout>

MainActivity.java :

classe publique CalPrime extends Activity
{
static final String UPPER_NUM = "upper";
EditText etNum;
CalThread calThread;
// Définition Une classe de thread
class CalThread extends Thread
{
public Handler mHandler;

public void run()
{ Looper.prepare(); 🎜>                                                                                                                         > Int UPPER = msg.getdata (). Getint (upper_num);
Integer & GT; <<> extérieur :
pour (int i = 2; i <= supérieur; i++)
                                                                                                                                                                                                                                                                                                                          ;= Math.sqrt(i)
;                                                                                                                                                                                                
continuer à l'extérieur
                                                                                                                         //Utilisez Toast pour afficher tous les nombres premiers comptés
, Toast.makeText(CalPrime.this, nums.toString()
, Toast.LENGTH_LONG).show() ;                                                                                                               } ; .onCreate(savedInstanceState);
setContentView(R.layout.main);
etNum = (EditText)findViewById(R.id.etNum);
calThread = new CalThread(); Démarrer un nouveau fil de discussion
calThread. start();
}
// Fournit une fonction de gestionnaire d'événements pour l'événement de clic sur le bouton
public void cal(View source)
{
// Créer message
Message msg = new Message();
msg.what = 0x123;
Bundle bundle = new Bundle();
bundle.putInt(UPPER_NUM,
Integer .parseInt(etNum. getText().toString()) );
msg.setData(bundle);//Envoyer un message au gestionnaire dans le nouveau fil de discussion
calThread.mHandler.sendMessage(msg);
}
}

PS : Cet exemple vient de "Android Crazy Handout" ~


Résumé de cette section

Cette section effectue une analyse simple de la livraison des événements Handler dans Android. Il est nécessaire de distinguer Handler, Message, MessageQueue, Le concept de Loop, et la différence entre Handler écrit dans le thread principal et le sous-thread !