当前位置:网站首页>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:

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:
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

ThreadLocal Créer un code source

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.ProcessussendMessage -> sendMessageAtTime -> enqueueMessageIn enqueueMessage Moyenne,Il y a un codemsg.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::
- 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();EtLooper.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 .

- 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:Par
Looper.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. .

- 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 :
- 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; } } } }- 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:
Message message = new Message();Message message1 = Message.obtain();En regardant le code source, J'ai aussi trouvé l'appel interne obtain() Méthodes.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é
🤩
️
边栏推荐
- 问个sql view的问题
- Redis' contribution in the field of microservices
- Cohere、OpenAI、AI21联合发布部署模型的最佳实践准则
- Redis scenario
- Summary of the process of restoring damaged data in MySQL database
- One hour is worth seven days! Ingenuity in the work of programmers
- SAP QM qac1 transaction code cannot modify the quantity in the inspection lot containing Hu
- Main steps of system test
- The data value reported by DTU cannot be filled into Tencent cloud database through Tencent cloud rule engine
- CVPR 2022 | 美团技术团队精选论文解读
猜你喜欢

One article explains R & D efficiency! Your concerns are

Several common DoS attacks

Kubernetes cluster deployment

Cloud native essay solicitation progress case practice

3. caller service call - dapr

Developer survey: rust/postgresql is the most popular, and PHP salary is low

开发者调查:Rust/PostgreSQL 最受喜爱,PHP 薪水偏低

LVGL库入门教程 - 颜色和图像

Creation and use of unified links in Huawei applinking

Nifi from introduction to practice (nanny level tutorial) - environment
随机推荐
Introduction to reptile to give up 01: Hello, reptile!
Brief introduction to cluster analysis
kotlin 关键字 扩展函数
Use abp Zero builds a third-party login module (I): Principles
The data value reported by DTU cannot be filled into Tencent cloud database through Tencent cloud rule engine
‘高并发&高性能&高可用服务程序’编写及运维指南
kotlin 继承、类、重载
Comparator 排序函数式接口
TCP triple handshake
Google Earth Engine——1999-2019年墨累全球潮汐湿地变化 v1 数据集
Opengauss kernel: simple query execution
kotlin 协程 lanch 详解
What should I do if I fail to apply for the mime database? The experience from failure to success is shared with you ~
[log service CLS] Tencent cloud log service CLS accesses CDN
AGCO AI frontier promotion (6.24)
Talk about GC of JVM
Kubernetes cluster deployment
kotlin 初始化块
Detailed explanation of abstractqueuedsynchronizer, the cornerstone of thread synchronization
面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?
