基于Kotlin解决Android中Handler内存泄漏问题

96
水月沐風
0.4 2018.09.19 14:01 字数 144
作为Android开发者,我们都知道,当我们在子线程处理完耗时任务后刷新UI时,一般会借助于 `Handler` 来实现。关于handler具体用法这里不做说明了,在使用 `Handler` 时一般会遇到内存泄漏的隐患,同时编译器也会给出一大片黄色的警告,在两者驱使下,我们势必要对其暴露的问题进行合理解决。

​ 关于Handler内存泄漏原因的详细分析可以参考该文章:https://www.jianshu.com/p/f2f186e3dd3e

这里我们主要来看一下在kotlin语言下如何处理handler内存泄漏问题。一般地,我们都会借助于静态内部类与弱引用来处理这类问题,kotlin中也不例外,这里以在fragment中为例,来看看实现代码吧:

private var handler: Handler = WithoutLeakHandler(this)

companion object {
        const val GET_LOCAL_VIDEOS: Int = 100
        /**
         * by moosphon on 2018/09/16
         * desc: 解决handler内存泄漏的问题,消息的处理需要放在内部类的{@link #Handler.handleMessage}
         */
        private class WithoutLeakHandler( fragment: VideoLocalFragment) : Handler(){
            private var mFragment: WeakReference<VideoLocalFragment> = WeakReference(fragment)

            override fun handleMessage(msg: Message) {
                super.handleMessage(msg)
                when(msg.what){
                    GET_LOCAL_VIDEOS -> {
                        val fragment = mFragment.get()

                        Log.e("VideoLocalFragment", "收到视频搜索完毕的消息了")
                        if (fragment != null){
                            fragment.adapter.setData(fragment.videoData!!)
                            fragment.fm_video_local_rv.adapter = fragment.adapter
                        }

                    }
                }
            }
        }
    }
    
    ......
    
     Thread(Runnable {
            videoData = MediaUtils.getLocalVideos(context)
            Log.e("VideoLocalFragment", "扫描本地视频的数量为->"+videoData?.size)
            val message= Message()
            message.what = GET_LOCAL_VIDEOS
            handler.sendMessage(message)
        }).start()
    

在kotlin中,我们需要在静态类 WithoutLeakHandler 中重写 handleMessage 方法,并在里面处理消息和刷新UI。

Android日常系列
Web note ad 1