[Android] [Memory Leak] Inputmethodmanager memory leak phenomenon and its solution

Source: Internet
Author: User

[Android] [Memory Leak] Inputmethodmanager memory leak phenomenon and its solution

phenomena :

on the k_touch_v9 model of a particular model , an interface appears Inputmethodmanager hold a Activity, causes the Activity cannot be recycled . if the Activity be opened again , then the old ones will be released. , but the newly opened will continue to be held unable to release the recycle . The MAT shows the Path to GC as follows :

Figure 1. Leak Path

Sky language k_touch_v9 Mobile phone version information :

Figure 2. K_touch_v9

after a search , someone has already met this problem. ( See the article at the end of the quote link ), the method given is :

@Overridepublic void Ondestory () {    //fix memory leak:http://code.google.com/p/android/issues/detail?id=34731    Inputmethodmanager IMM = (inputmethodmanager) getsystemservice (context.input_method_service);    Imm.windowdismissed (This.getwindow (). Getdecorview (). Getwindowtoken ()); Hide method    imm.startgettingwindowfocus (null);//Hide Method    super.ondestory ();}


But after use in practice , not really solved , Activity still exists , but Path to GC Point to unknown. as :

Figure 3. Unknownpath

the code you searched for doesn't work . , we'll find a way . .

Want to let Activity Let it out . , the idea is to Path TOGC This link can be cut off . in this Bug There are two nodes on this link. Mcontext (Decorview) and the Mcurrootview (Inputmethodmanager) available for consideration . The following idea is to select one of the two nodes to start cutting Path to GC can be .

Read the source, Decorviewinherit fromFramelayout,mcontextis its contextual environment,too much involved .,not suitable for operation start. Mcurrootviewin theInputmehtodmanagerIt's a lot easier to use in the,after the assignment is initialized,The scene used is only one judgment and one log print.so check here .Mcurrootviewas a breakthrough.The operation to cut its path to GC is to use the Java Reflection method to Mcurrootview Empty can be(See code after text).

after the encoding is implemented , re-Test , found that there was still a leak , But the leak has changed . , as :

Figure 4. Leak Path

         The new leak point isMservedview/mnextservedview,can pass the samejavareflectionPlace it empty,Cut offpath to GC.But here's a question to be careful about.,after forcing the empty space here,will it causeInputmethodmanagerof theNullPointerException??will cause the internal logic of the system to crash?Check the source again,foundMservedviewandMnextservedviewalways have empty logic in the code logic,so you can safely force empty to solve the problem..


Figure 5. null logic

The final post code implementation :

              public static void Fixinputmethodmanagerleak (context context) {if (context = = Nu                            ll) {return; } try {//to Mcurrootview Mservedview Mnextservedview                                          Make empty ...                                          Inputmethodmanager IMM = (inputmethodmanager) context.getsystemservice (Context.input_method_service);                                          if (IMM = = null) {return; }//Author:sodino mail:[email protected] Object obj                                          _get = null;                                          Field F_mcurrootview = Imm.getclass (). Getdeclaredfield ("Mcurrootview");                         Field F_mservedview = Imm.getclass (). Getdeclaredfield ("Mservedview");                 Field F_mnextservedview = Imm.getclass (). Getdeclaredfield ("Mnextservedview"); if (f_mcurrootview.isaccessible () = = False) {F_MCU                                          Rrootview.setaccessible (TRUE);                                          } Obj_get = F_mcurrootview.get (IMM);                                           if (obj_get! = null) {//NOT NULL is set to null f_mcurrootview.set (IMM, NULL); } if (f_mservedview.isaccessible () = =                                          False) {f_mservedview.setaccessible (true);                                          } Obj_get = F_mservedview.get (IMM);                            if (obj_get! = null) {//NOT NULL is set to NULL                            F_mservedview.set (IMM, NULL);                                                        } if (f_mnextservedview.isaccessible () = = False) {                                          F_mnextservedview.setaccessible (TRUE);                                          } Obj_get = F_mnextservedview.get (IMM); if (obj_get! = null) {//NOT NULL is set to null f_mnextservedview.set (IMM, Nu                                          ll);                            }} catch (Throwable t) {t.printstacktrace (); }              }


This can be resolved by executing the above method in the activity.ondestory () method .

              Public  void OnDestroy () {                            Super.ondestroy ();                            Fixinputmethodmanagerleak (this);              }

It seems to be a complete solution, but really?

After the above processing, the memory leak is not present, but there is another problem, is the place of the input box, click the input box, but can not appear the input interface!

The operation steps for the accident site recurrence are:

Activitya interface, click into Activity b interface, B has an input box, click the input box, no Input Method pop-up. The reason is that Inputmethodmanager's associated view has been empty by the code above.

The cause of the accident starts with the sequence of life cycle method calls between the activity:

The sequence of calls from activity A into activity B's life cycle method is:


In other words, Activity B has been created and displayed, Activitya here performs OnDestroy () to empty the associated view of Inputmethodmanager, causing the input method to not eject.

The reason is found, it is easy to solve.

The Fixinputmethodmanagerleak (contextdestcontext) method parameter passes the target activity A to be destroyed as a parameter. In the code, to get the associated view of Inputmethodmanager, by comparing View.getcontext () with activity A, if the two are found to be the same, it means recycling; It means that there is a new interface already in use Inputmethodmanager, directly do not deal with it.

After the modification, the final code is as follows:

public static void Fixinputmethodmanagerleak (Context destcontext) {if (Destcontext = = null) {return;} Inputmethodmanager IMM = (inputmethodmanager) destcontext.getsystemservice (Context.input_method_service); if (IMM = = NULL) {return;} String [] arr = new string[]{"Mcurrootview", "Mservedview", "Mnextservedview"}; Field f = null;object obj_get = null;for (int i = 0;i < Arr.length;i + +) {String param = Arr[i];try{f = Imm.getclass (). Getdeclaredfield (param); if (f.isaccessible () = = False) {f.setaccessible (true);}//Author:sodino mail:[email  Protected]obj_get = F.get (IMM); if (obj_get! = null && obj_get instanceof view) {View V_get = (view) obj_get;if (v_ Get.getcontext () = = Destcontext) {//Inputmethodmanager holding the referenced context is the F.set (IMM, NULL) that wants the target to be destroyed;//empty, destroy path to GC node} ELS e {//do not want to destroy the target, that is, another layer of interface, do not handle, to avoid affecting the original logic, you do not have to continue for the loop of if (Qlog.iscolorlevel ()) {QLOG.D ( ReflecterHelper.class.getSimpleName (), QLOG.CLR, "Fixinputmethodmanagerleak break, context was not suitable, get_ Context= "+ V_get.getcontext () + "dest_context=" + Destcontext);} Break;}}} catch (Throwable t) {t.printstacktrace ();}}}


References :

l Inputmethodmanager:googlecode

l Activity leaks due to Inputmethodmanger

l mainactivity isn't garbage collected after destruction because it's referenced Byinputmethodmanager indirectly

l Inputmethodmanagerholds Reference to the Tabhost-memory leak-oom Error

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.