标签:内存泄露 科大讯飞 inputmethodmanager
1 今天在调试android 程序时候,发现即使程序退出了,发现还占用内存大概有15M.用MAT查看,经过多次GC操作,发现依旧是15.直觉告诉我,应该发生内存泄露了。然后利用MAT,查看Memory Leak。结果让我很吃惊,发现是InputMethodManager。这个对象一直引用着Context。也就是Activity,导致它无法释放内存。后来google 一下发现,
以下贴出解决办法,希望给遇到类似情况的人,提供帮助:
@Override protected void onDestroy() { super.onDestroy(); //fix for memory leak: http://code.google.com/p/android/issues/detail?id=34731 fixInputMethodManager(); } private void fixInputMethodManager() { final Object imm = getSystemService(Context.INPUT_METHOD_SERVICE); final Reflector.TypedObject windowToken = new Reflector.TypedObject(getWindow().getDecorView().getWindowToken(), IBinder.class); Reflector.invokeMethodExceptionSafe(imm, "windowDismissed", windowToken); final Reflector.TypedObject view = new Reflector.TypedObject(null, View.class); Reflector.invokeMethodExceptionSafe(imm, "startGettingWindowFocus", view); }就是通过反射调用windowDismissed和startGettingWindowFocus。本来以为这个问题就这样搞定了,谁知道又出现了一个更加奇葩的情况。我发现竟然还有一个更奇葩的对象:com.lflytek.speech.a.a.a。脑子懵了一下,这是啥东东?通过百度这个查询,发现这是科大讯飞的语音识别sdk。对,脑子确实懵了。但是不对啊。这个对象怎么生命周期那么长。不对,肯定哪里搞错了。后来通过源代码阅读:
public RecognizerDialog(Context paramContext, String paramString) { super(paramContext); this.a = new a(paramContext, paramString); } public void setListener(RecognizerDialogListener paramRecognizerDialogListener) { ((a)this.a).a(paramRecognizerDialogListener); }这是sdk唯一能得到我应用程序的地方,其他的都是设置一些信息。难道问题就出在这个地方?对,你答对了!
表面上看起来这没有任何问题,你看我们很多应用程序sdk不都是这么弄的嘛,这很正常啊。没办法,虽然代码混淆过了,可我为了搞清楚事情真相只能硬着头皮去读。通过代码不断的追踪,终于发现秘密了。
在com.iflytek.speech.a.a中有一个很奇葩的私有的类成员。
private static a e=null
public static com.iflytek.speech.b b(Context paramContext, String paramString) { if (e == null) e = new a(paramContext, paramString); return e; }
以下贴出反射的代码。
@Override public void finish() { com.iflytek.a.a.a=null; try { Class clazz=Class.forName("com.iflytek.speech.a.a"); Field field=clazz.getDeclaredField("e"); if (field.isAccessible()==false) { field.setAccessible(true); } field.set(null, null); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } super.finish(); }
看来以后用第三方sdk的时候,得注意点了,不能随便用啊。
标签:内存泄露 科大讯飞 inputmethodmanager
原文地址:http://blog.csdn.net/asking1233/article/details/45101367