当前位置:网站首页>Manuel d'entrevue du gestionnaire de l'analyse des sources

Manuel d'entrevue du gestionnaire de l'analyse des sources

2022-06-24 13:34:00 Huawei Cloud

@[TOC](Handler Analyse des sources d'entrevue dictionnaire d'entrevue

Préface

InAndroid De,Entretien avancé,On nous demande souventHandler Points de connaissance pertinents,Et la proportion de poids est assez élevée,Qu'est - ce que c'est??Voyons une image:

En fait, un téléphone portable,Juste un.Handler,

Comme le montre la figure ci - dessus,ToutAPP Processus de démarrage pour: Launcher(APP): zygote -> jvm -> ActivityThread.main()ActivityThread.main() C'est nousAPP Uniquemain Méthode de démarrage,Comme le montre la figure,La partie verte,C'estHandler L'espace unique qui nous a été ouvert,Unique au thread principal de démarrageLooper,Va maintenantApp Indépendant.

Nous pouvons donc conclure que:Handler Ce n'est pas seulement la communication de processus,La communication de processus est justeHandler Fonction accessoire de,EtHandler La vraie fonction de Tous les codes,Tout est dansHandler En cours d'exécution

1、Un thread a plusieursHandler

Point d'examen

Ce que l'intervieweur veut savoir, c'est que,Tu as raisonHandlerCognition, Si cette question ne se pose pas, , Alors l'intervieweur ne demandera plus jamais .

La réponse

Avant de répondre , Regardez d'abord tout le temps Handler Organigramme d'exécution pour:
Insérer la description de l'image ici

Par la figure ci - dessus,Nous pouvons voir:

  • Dans un fil ,Peut être crééN- Oui.Handler,Par exemple:hander.sentXXX、 handler.postXX Sont en train de créer un Handler. Chaquemessage, C'est que nous insérons dans la file d'attente des messages Noeud de message dans .

2、Un thread a plusieursLooper?Comment garantir

Point d'examen

Ce que l'intervieweur veut savoir, c'est que,Tu as raisonHandler Compréhension du processus et du code source .

La réponse

  • Avant de répondre à cette question,Regardons encore.Handler Organigramme d'exécution pour:
    handler -> sendMessage -> messageQueue.enqueueMessage -> looper.loop() -> messasgeQueue.next() -> handler.dispatchMessage() -> handler.handerMessage() ,handler Envoyermessage,EntréemessageQueue.enqueueMessage File d'attente,EntréelooperPassage moyenloop La traversée constante du cycle de la mort , La file d'attente continue ,Passe.handler.dispatchMessage() Distribué à:handler.handerMessage, Comme ça, on a fini. Handler Processus, Ou vous pouvez vous tromper directement ,Dans un fil,Un seulLooper.
  • Comment le garantir??ThreadLocal Multithreading,Variables de stockage pour le contexte du thread,En fait...ThreadLocal Ne stocke rien. ,Mais dansThreadLocal Moyenne,Il y a unThreadLocalMap Ensemble,Ce qui est stocké à l'intérieur<this, value> ,this C'est le contexte.,UniqueThreadLocal key,key Le seul. ,Alorsvalue C'est le seul.,ThreadLocalAu moment de la création,Il y aura un jugement,Si vous avez créé,Exception signalée, Donc un thread a un ThreadLocal Il n'y a que looper.Comme le montre la figure ci - dessous::

ThreadLocal Classe d'outils d'isolement des fils

Insérer la description de l'image ici

ThreadLocal Créer un code source

Insérer la description de l'image ici

3、Handler Raison de la fuite de mémoire? Pourquoi les autres classes internes n'ont pas dit ça?

Point d'examen

L'examinateur doit se demander ,Votre opinion surGCRecyclage JVM Quelque chose de pertinent.

La réponse

Ici, Je vais commencer par un code. :

    Handler handler = new Handler(){        @SuppressLint("HandlerLeak")        @Override        public void handleMessage(@NonNull Message msg) {            Log.d("tiger", "handleMessage: ");            View view = null;            click(view);            MainActivity2.this.click(view);        }    };    public void click(View view) {            }
  • Dans le fragment de code ci - dessushandler Code, Monogramme jaune , Et donne un avertissement : Cette classe de gestionnaire devrait être statique ,Sinon, une fuite de mémoire peut se produire.
  • Alors pourquoi n'y a - t - il pas d'autres classes? ?
    Problèmes liés au cycle de vie.Processus sendMessage -> sendMessageAtTime -> enqueueMessage In enqueueMessage Moyenne,Il y a un code msg.target = this;,Ça veut dire...Message Va tenir le courant handler,handler Est devenumassageUne partie de, Si je mets un message en attente 20Exécution dans quelques minutes, Alors ça veut dire ,MonmessageIl attendra toujours20 Pas avant quelques minutes ,message Détention handler,handler Détention (this)activity,Cela conduit àGCImpossible de recycler,JVM Grâce à l'algorithme d'accessibilité,Dis - nous., Impossible d'atteindre ,Ne peut pas être recyclé. Cycle de vie des classes internes , Une fois qu'il est détenu par un autre cycle de vie dans le cycle de vie d'une classe externe , Les classes externes ne peuvent pas non plus être libérées .

4、Pourquoi le fil principal peutnew Handler?Si vous voulez être dans un sous - threadnew Handler Que faire??

Point d'examen

C'est ennuyeux,Je ne sais pas., Pourquoi demander ça? ?

La réponse

  • InAPP Au démarrage,Juste là.ActivityThread.main() Dans la méthode,Juste créélooper.loop() ,Le code source est le suivant::
    Insérer la description de l'image ici
  • Alors comment dans un sous - fil new HandlerEt alors?? Tout ce qu'il faut, c'est que dans le Sous - fil ,Ajouter manuellement Looper.prepare(); Et Looper.loop(); C'est bon.Regardez le code ci - dessous
    public void click (View view){            new Thread(new Runnable() {                @Override                public void run() {                    Looper.prepare();                    mHandler = new Handler() {                        public void handleMessage(Message msg) {                            // do something()                        }                    };                    Looper.loop();                }            }).start();        }

5、Maintenu dans le Sous - threadLooper, Quelle est la méthode de traitement lorsqu'il n'y a pas de message dans la file d'attente des messages? ?À quoi bon??

Point d'examen

Maîtrise du code source

La réponse

  • Maintenu dans le Sous - threadLooper Appelé en l'absence de message quit, Peut mettre fin au cycle .loop() C'est un cycle mort,Pour sortir,Il fautmsg == null. Regardez le code source ci - dessous :
public static void loop() {        for (;;) {            Message msg = queue.next(); // might block            if (msg == null) {                // No message indicates that the message queue is quitting.                return;            }            msg.recycleUnchecked();        }    }
  • Seulement si vous appelezquit Quand,Pour revenirnull.
Message next() {        for (;;) {            synchronized (this) {                if (mQuitting) {                    dispose();                    return null;                }            }        }    }void quit(boolean safe) {        synchronized (this) {            if (mQuitting) {                return;            }            mQuitting = true;        }    }
  • Alors utilisezquit() Réveillez la file d'attente,Mise en œuvreloop() Cycle de sortie,Sous - threadlooper Pas en cours d'exécution .

Insérer la description de l'image ici

  • Les nouvelles arrivent.:Trier par heure,Quand la file d'attente est pleine,Blocage,Jusqu'à ce que l'utilisateur passenext() Supprimer le message.Quandnext Lorsque la méthode est appelée,NotificationMassageQueue On peut entrer dans l'équipe .
  • Le message sort de l'équipe:ParLooper.loop()Faire un cycle, C'est exact.queue Effectuer un sondage,Quand le message atteint le temps d'exécution,QuandMessageQueue Quand c'est vide,Blocage de la file d'attente, Attendez que le message appelle queue massage Quand,File d'attente de notification, Vous pouvez récupérer le message ,Arrêtez le blocage.
  • handler Les files d'attente bloquées dans plusieurs Threads ne sont pas utilisées BlockQueue,Parce que le fil principal(Système)Est également utilisé,Si vous utilisezBlockQueue Si la limite supérieure est fixée , Le système peut être bloqué, etc. .

Insérer la description de l'image ici

  • De l'image ci - dessus, On peut voir que ,handler Est un producteur - Modèle de conception du consommateur .Voyons voir.,looper Deux modes de blocage du cycle :
  1. Blocage du temps d'exécution ( Pas de temps d'exécution ),nativePollOnce(long ptr, int timeoutMillis) Effectuer une opération de blocage,timeoutMillis Pour -1 Indique une attente infinie, Jusqu'à ce que l'événement se produise ,Si oui0,Pas besoin d'attendre,Exécution immédiate. Regardez le code source ci - dessous :
    Message next() {        final long ptr = mPtr;        if (ptr == 0) {            return null;        }        int nextPollTimeoutMillis = 0;        for (;;) {            nativePollOnce(ptr, nextPollTimeoutMillis);//  Circulation dans un état bloqué , Réveil en attendant l'heure d'exécution             synchronized (this) {                if (msg != null) {                    if (now < msg.when) {                        // Le message n'est pas vide, Et il n'y a pas de temps d'exécution ,nextPollTimeoutMillis Non.-1                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);                    }                }                // Process the quit message now that all pending messages have been handled.                if (mQuitting) {                    dispose();                    return null;                }            }        }    }
  1. MessagaQueue Vide,Blocage de l'exécution,Attendez de vous réveiller. Lors de l'insertion d'un message ,Réveil actif, Regardez le code source ci - dessous :
    Message next() {        if (ptr == 0) { // mPtr==0, Indique un cycle d'interruption ,            return null;        }        int pendingIdleHandlerCount = -1;        int nextPollTimeoutMillis = 0;        for (;;) {            nativePollOnce(ptr, nextPollTimeoutMillis);            synchronized (this) {                if (msg != null) {                } else {                    // Aucune nouvelle,timeoutMillisPour-1Indique une attente infinie,Jusqu'à ce qu'un incident se produise                    nextPollTimeoutMillis = -1;                }            }        }    }    // mPtr==0    private void dispose() {        if (mPtr != 0) {            nativeDestroy(mPtr);            mPtr = 0;        }    }    // Réveillez - vous.    boolean enqueueMessage(Message msg, long when) {        synchronized (this) {            boolean needWake;            Message p = mMessages;            if (p == null || when == 0 || when < p.when) {                msg.next = p;                mMessages = msg;                needWake = mBlocked;            }            // mPtr != 0  Le cycle n'est pas interrompu ,Effectuer une opération de réveil.            if (needWake) {                nativeWake(mPtr);            }        }        return true;    }

6、Comme il peut y en avoir plusieursHandler Allez.MessageQueue Ajouter des données(Chaque fois qu'un message est envoyéHandler Peut être dans un thread différent),Comment s'assure - t - il que les fils sont sécurisés à l'intérieur?

Point d'examen

Verrouillage du fil, Plus tard. synchronized Quelque chose de pertinent

La réponse

  • synchronizedVerrouillage: synchronizedVerrouillage intégré,C'est fait parjvmAuto - completed, La serrure est nécessaire pour l'insertion et la récupération , Parce que quand je l'ai pris , Peut - être insérer . C'est l'objet de la serrure ,Parce queMessageQueue Il n'y en a qu'un par filLooper,ChaqueLooper Il n'y en a qu'un autre MessageQueue.

7、Nous utilisonsMessage Comment le créer?

Point d'examen

Tu veux savoir si tu l'as utilisé? ?

La réponse

  • CréationMessage Quand l'objet,Il y a trois façons:
  1. Message message = new Message();
  2. Message message1 = Message.obtain(); En regardant le code source, J'ai aussi trouvé l'appel interne obtain() Méthodes.
  3. Message message2 = handler.obtainMessage();

8、Looper Pourquoi la boucle morte ne provoque - t - elle pas le blocage de l'application

Point d'examen

Est - ce que c'est ANR Mécanisme?

La réponse

  • L'application est bloquée. ANR,Qu'est - ce que c'est?ANR?ANR Comment détecter ,J'ai compris.ANR Comment détecter ,On le savait.LooperPourquoi la boucle morte ne provoque - t - elle pas le blocage de l'application?

Qu'est - ce queANR?

  • ANR Cela signifie que l'application ne répond pas ,ANR Le corps principal est implémenté au niveau du système .TousANRMessages connexes, Qui passent par le processus du système (AMS)Répartition, Il est ensuite envoyé au processus d'application pour compléter le traitement réel du message. ,En même temps, Les processus du système ont conçu différentes limites de temps d'arrêt pour suivre le traitement des messages. . Une fois que l'application a mal traité le message , La limite de temps d'arrêt fonctionne , Il recueille certains états du système ,Par exemple,CPU/IOUtilisation、 Pile d'appels de fonctions de processus , Et signale que l'utilisateur a un processus qui ne répond pas (ANRBoîte de dialogue).

Résumé

🤩
L'originalité n'est pas facile,Et j'espère que les grands hommes vous soutiendront. \textcolor{blue}{L'originalité n'est pas facile,Et j'espère que les grands hommes vous soutiendront.}

- Oui.,Votre reconnaissance est la force motrice de ma création! \textcolor{green}{- Oui.,Votre reconnaissance est la force motrice de ma création!}

Collection,Votre faveur est la direction de mes efforts! \textcolor{green}{Collection,Votre faveur est la direction de mes efforts!}

Commentaires,Votre opinion est un atout pour mon progrès! \textcolor{green}{Commentaires,Votre opinion est un atout pour mon progrès!}

原网站

版权声明
本文为[Huawei Cloud]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/175/202206241234579761.html