七. 总搅一皓留意点
大年夜概情况是如许:WebView 这套构造中,有一个工厂类 WebViewFactory 供给静态办法。
Android4.3(JellyBean) 版本经由过程 WebViewFactory 工厂类创建了一个全局单例对象 WebViewClassic$Factory,然后应用这个 Factory 创建了一整套实现的代码(XXXClassic):WebViewClassic, CookieManagserClassic, WebViewDatabaseClassic。
WebViewClassic 才是真正地实现 WebView 的各类 API。WebViewClassic 创建并保护了 WebViewCore 对象。
WebViewCore 创建了一个子线程“WebViewCoreThread”,这里是一个全局的单例的并且一旦启动就不会停止的 Thread!WebViewCore 会在这个子线程中创建保护并调用 BrowserFrame 的办法。
BrowserFrame 本身是一个属于“WebViewCoreThread”线程的 Handler 子类。BrowserFrame 会被 native(c++) 层调用,然后将这些调用切换到“WebViewCoreThread”线程中去履行,比如刷新进度或者处理屏幕扭转事宜等等。
BrowserFrame 还会调用 CookieSyncManager.createIntance(),这也是体系框架中独一一处调用的处所!

看到这里之后,楼主发明以上所说的,提前帮体系调用
CookieSyncManager.createInstance(contenxt.getApplicationContext()) 可能是没有效不雅的,因为体系本来就是这么做的。手机厂商修改┞封里的可能性不大年夜。
CookieSyncManager 又是什么器械?同样的,它本身也创建一个子线程,线程名就叫“CookieSyncManager”,又是全局单例不会停!这个线程每过5分钟就会把缓存在内存中的 Cookie 进行持久化 syncFromRamToFlash()。
这里我们比较关怀为什么 Activity 会泄漏,所以关键看看哪些类对象中持有了 Activity(Context) 引用:WebViewClassic, WebViewCore, BrowserFrame。
这套构造中有很多静态单例,还有子线程,想想也挺恶心的。并且三个关键的类都持有 Activity 引用。不过我们发明,其实 WebViewClassic, WebViewCore 这两个个对象跟 WebView 对象的生命周期是一致的,Activity 烧毁于是 WebView 烧毁了,WebView 烧毁了别的两个对象也跟着烧毁。烟消云散。。。
留下两个孤单的子线程还在跑,还有全局静态的钉子户对象。
然则!BrowserFrame 本身是 Handler,假如它因为 native 层的调用往”WebViewCoreThread”挂了一个消息,那么便可以建立一条引用链:
Thread->MessageQueue->Message->Handler(BrowserFrame)->Activity

好了,楼主的困惑是什么?
这里扼要解释一下,作者的结论是:在 Android Lollipop 之前应用 AlertDialog 可能会导致内存泄漏!
五. 最后的困惑

楼主发明,这里 CookieSyncManager 线程,居然直接引用了 Message 对象!这是什么鬼?一般情况下,HandlerThread 持有一个 MessageQueue 对象,MessageQueue 才持有 Message 队列。
Input or output parameters in native code, for example user-defined JNI code or JVM internal code. Many methods have native parts, and the objects that are handled as method parameters become garbage collection roots. For example, parameters used for file, network, I/O, or reflection operations.
这里注解,CookieSyncManager 线程中存在某个 Message 的局部变量,而因为线程一向没有停止,所以局部变量一向没有被释放。而这个 Message.obj 成员引用了 AuthDialog$3 对象。
这是一个内部类,楼主发明内部类混淆之后的定名规矩就是:第几个出现就定名为几。
AuthDialog 琅绫擎有很多内部类:


纳尼!OnDismissListener 居然被赋给了 Message.obj 成员!
于是,我们心中生成的一条引用链是如许的:
Thread(main) -> MessageQueue->Message -> obj(OnDismissListener) -> AuthDialog -> Activity

二. WebView 导致内存泄漏众所周知
可是纰谬啊,我们所能找到的引用链跟 CookieSyncManager 子线程一点关系都没有!
再比较一下:

子线程 CookieSyncManager 拿到了主线程的 Message!! Oh no !! 这是什么情况???这个 Message 被某处处所缺点引用了?子线程经由过程 JNI 在 native 中拿到 Java 层的对象?
好吧,楼主承认研究了一个晚膳绫腔有任何进展。。。
Dialog 自负年夜拥有了 mDismissMessage 对象之后就不会让它挂到消息队列中了,每次要用都是拷贝一份罢了。Message.obtain(mDismissMessage),所以这个 Message 再也不会回到收受吸收藏中,直到 Dialog 被烧毁,mDismissMessage 变量也被置为 null 了。
推荐阅读
4)始终供给关于异常的有意义的完全的信息异常处理是Java 开辟中的一个重要部分。它是关乎每个应用的一个非功能性需求,是为了处理任何缺点状况,比如资本弗查拜访,不法输入,空输入等等>>>详细阅读
本文标题:Android中导致内存泄漏的竟然是它----Dialog
地址:http://www.17bianji.com/lsqh/35540.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示