content: package com.cicada.player.demo.util;
  
  import android.app.Activity;
  import android.content.Context;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.ViewParent;
  import android.view.inputmethod.InputMethodManager;
  import android.webkit.WebView;
  
  import java.lang.reflect.Array;
  import java.lang.reflect.Field;
  
  /**
   * Created by lifujun on 2017/9/29.
   */
  
  public class CleanLeakUtils {
  
      private static final String TAG = CleanLeakUtils.class.getSimpleName();
  
      public static void fixInputMethodManagerLeak(Context destContext) {
          if (destContext == null) {
              return;
          }
  
          InputMethodManager inputMethodManager = (InputMethodManager) destContext.getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
          if (inputMethodManager == null) {
              return;
          }
  
          String[] viewArray = new String[]{"mCurRootView", "mServedView", "mNextServedView", "mLastSrvView", "mLastSrvView"};
          Field filed;
          Object filedObject;
  
          for (String view : viewArray) {
              try {
                  filed = inputMethodManager.getClass().getDeclaredField(view);
                  if (!filed.isAccessible()) {
                      filed.setAccessible(true);
                  }
                  filedObject = filed.get(inputMethodManager);
                  if (filedObject != null && filedObject instanceof View) {
                      View fileView = (View) filedObject;
                      if (fileView.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
                          filed.set(inputMethodManager, null); // 置空，破坏掉path to gc节点
                      } else {
                          break;// 不是想要目标销毁的，即为又进了另一层界面了，不要处理，避免影响原逻辑,也就不用继续for循环了
                      }
                  }
              } catch (Throwable t) {
  //                VcPlayerLog.e(TAG , "e : " + t.getMessage());
              }
          }
      }
  
  
      /**
       * 修复华为手机内存的泄露
       */
      public static void fixHuaWeiMemoryLeak(Activity activity) {
          //测试
          try {
              Class<?> GestureBoostManagerClass = Class.forName("android.gestureboost.GestureBoostManager");
              Field sGestureBoostManagerField = GestureBoostManagerClass.getDeclaredField("sGestureBoostManager");
              sGestureBoostManagerField.setAccessible(true);
              Object gestureBoostManager = sGestureBoostManagerField.get(GestureBoostManagerClass);
              Field contextField = GestureBoostManagerClass.getDeclaredField("mContext");
              contextField.setAccessible(true);
              if (contextField.get(gestureBoostManager) == activity) {
                  contextField.set(gestureBoostManager, null);
              }
          } catch (ClassNotFoundException e) {
          } catch (NoSuchFieldException e) {
          } catch (IllegalAccessException e) {
          } catch (Throwable t) {
          }
      }
  
      public static void fixHuaWeiPhoneWindowMemoryLeak() {
          try {
              Class<?> hwPhoneWindowClz = Class.forName("com.android.internal.policy.HwPhoneWindow");
              Field mContextField = hwPhoneWindowClz.getDeclaredField("mContext");
              mContextField.setAccessible(true);
              Object hwPhoneWindow = mContextField.get(hwPhoneWindowClz);
              mContextField.set(hwPhoneWindow, null);
          } catch (ClassNotFoundException e) {
          } catch (NoSuchFieldException e) {
          } catch (IllegalAccessException e) {
          }
      }
  
      public static void freeWebview(WebView webView) {
          ViewParent parent = webView.getParent();
          if (parent != null) {
              ((ViewGroup) parent).removeView(webView);
          }
  
          webView.stopLoading();
          // 退出时调用此方法，移除绑定的服务，否则某些特定系统会报错
          webView.getSettings().setJavaScriptEnabled(false);
          webView.clearHistory();
          webView.clearView();
          webView.removeAllViews();
  
          try {
              webView.destroy();
          } catch (Throwable ex) {
  
          }
      }
  
      public static void fixTextLineCacheLeak() {
          Field textLineCached = null;
          try {
              textLineCached = Class.forName("android.text.TextLine").getDeclaredField("sCached");
              textLineCached.setAccessible(true);
          } catch (Exception ex) {
  
          }
          if (textLineCached == null) {
              return;
          }
          Object cached = null;
          try {
              // Get reference to the TextLine sCached array.
              cached = textLineCached.get(null);
          } catch (Exception ex) {
          }
          if (cached != null) {
              // Clear the array.
              for (int i = 0, size = Array.getLength(cached); i < size; i++) {
                  Array.set(cached, i, null);
              }
          }
      }
  }
  