package licola.demo.com.huabandemo.Util; import android.content.Context; import android.view.View; import android.view.inputmethod.InputMethodManager; import java.lang.reflect.Field; /** * Created by LiCola on 2016/05/28 1:43 */ public class LeakUtils { 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()) { f.setAccessible(true); } obj_get = f.get(imm); if (obj_get != null && obj_get instanceof View) { View v_get = (View) obj_get; if (v_get.getContext() == destContext) { // referenced context is held InputMethodManager want to destroy targets f.set(imm, null); // set empty, destroyed node path to gc } else { // Not want to destroy the target, that is, again into another interface, do not deal with, to avoid affecting the original logic, there is nothing further for the cycle Logger.d("fixInputMethodManagerLeak break, context is not suitable, get_context=" + v_get.getContext() + " dest_context=" + destContext); break; } } } catch (Throwable t) { t.printStackTrace(); } } } }