唉内存泄漏

大神的博客挂在前面
Android内存优化(六)LeakCanary使用详解
Android内存优化(三)避免可控的内存泄漏
使用LeakCanary检测安卓中的内存泄漏(实战)
#####要被内存泄漏搞死了,最近项目运行一段时间后就会oom,很烦的。查了很久,LeakCanary那个东西用了好像是我不会用什么反应,试了android studio自己自带的那个dump java heap好像也不会用,啥也没看出来,还用了mat工具,我觉得我是个蠢的,依然啥也没看出来。最后只能继续蠢,肉眼review代码,找到了有两处。
内存泄漏导致内存占用高到一定程度的时候,并不会立马oom闪出应用程序,而是会影响到程序的操作,你看着程序跑得好好的,但是你点击刷新或者其他操作的时候,程序是不会响应的,或者说他响应了但是并不能完成操作。操作台此时的日志和监察器的内存是这样的。
这里写图片描述

这里写图片描述

还有那个LeakCanary,在build.gradle中, 我添加

debugCompile ‘com.squareup.leakcanary:leakcanary-android:1.5.2’

它编译不通过

Error:Execution failed for task ‘:app:transformClassesWithDexForDebug’.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lcom/squareup/leakcanary/watcher/R;
这里写图片描述
踏马,我改成1.5它就好了。我要气死,也是从事开发一年多的人了,为什么还是遇到问题不知道为什么。愁死我了
#第一个地方:

#####我们知道在oncreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调后完成。所以现在需要使用
#####getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。 OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。ViewTreeObserver不能直接实例化,而是通过getViewTreeObserver()获得。

项目代码里动态获取TextView(menuCondiment)的行数,然后动态改变RecyclerView的高度,但是我只知道是这段代码引起了内存占用一直在涨,却不知道为什么会这样。因为按我的想法,每次调用OnGlobalLayoutListener之后都调用了menuCondiment.getViewTreeObserver().removeGlobalOnLayoutListener(this);进行移除,按理说不应该再泄漏了,但是实际情况很悲观,气死了,我只能注释掉了这段代码,目前还没找到好的方法。准备认真研究一下内存泄漏再来搞定它。好气好气。

            menuCondiment.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) viewMain.getLayoutParams();
                    int line = menuCondiment.getLineCount();
                    if (line > 2) {
                        params.height = DensityUtils.dp2Px(context, 48 + 30 * (line - 1));
                        viewMain.setLayoutParams(params);
                    }
                   menuCondiment.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                }
            });

#第二个地方:
这个就很明显了,bindOrderData()方法一直往集合里添加数据。
解决办法就是每次调用bindOrderData()方法的时候,把集合里的数据清掉

    private List<TextView> headerView = new ArrayList<>();
 
 private void bindOrderData() {
        //这里这里
        headerView.clear();
        ...
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值