美文网首页
尽量避免在java代码中过多使用view.setBackgrou

尽量避免在java代码中过多使用view.setBackgrou

作者: koinzhang | 来源:发表于2019-07-27 20:53 被阅读0次

博主最近在开发导师的一个项目,写了一个动态生成控件的组件,这个组件的基本功能是在一个父控件中生成若干个子控件,这些控件有拖动事件或者点击事件,原本在生成子控件个数较小时,没有什么问题,但如果子控件个数较多,页面就出现了卡顿。因为父控件是放在一个fragment中,这导致viewPager滑动切换页面时,不论是从本页面滑出还是滑入本页面,都会卡顿。同时子控件的拖动也会掉帧。
问题分析:
原以为是子控件个数较多导致了整个页面的卡顿,但博主在布局文件中预先布置多个子控件,页面竟不会卡顿。那么问题一定是出在了别的地方。使用Profiler查看了项目的性能分析结果,发现内存占用的大头是Graphics这一项,也就是页面的图形渲染,占到32M左右。
查阅资料之后,发现是因为在java代码中使用了setbackgroundrResource()这个函数导致的,所有子控件的background都是在java代码中设置的,这就导致了项目的OOM。
下面是动态生成子控件的代码:

                        TextView textView = new TextView(mContext);
                        mRelativeLayout.addView(textView);
                        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) textView.getLayoutParams();
                        layoutParams.height = (int) ((btn_row / FARM_ROW) * (farmHeight - 20));
                        layoutParams.width = (int) ((btn_column / FARM_COLUMN) * (farmWidth - 20));

                        layoutParams.topMargin = (int) (btn_y * farmHeight);
                        layoutParams.leftMargin = (int) (btn_x * farmWidth);
                        textView.setLayoutParams(layoutParams);
                        textView.setText(mJsonList.get(i).getString("name"));
                        textView.setTextColor(mContext.getResources().getColor(R.color.color_white));
                        textView.setBackgroundResource(R.drawable.bg_field);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            textView.setAutoSizeTextTypeUniformWithConfiguration(5, 13, 2, TypedValue.COMPLEX_UNIT_SP);
                        } else {
                            textView.setTextSize(9);
                        }
                        textView.setEms(1);
                        textView.setGravity(Gravity.CENTER);
                        textView.setTag(i);
                        if (action == DRAG_EVENT) {
                            textView.setOnTouchListener(moveTouchListenr);
                        } else if (action == CLICK_EVENT) {
                            textView.setOnClickListener(onClickListener);
                        }

问题解决:
既然在java代码中使用setBackgroundResource会导致OOM,但还是想要给子控件设置background,所以我利用inflate,加载一个在布局文件中已经写好的子控件布局,这样就避免了使用setbackgroundrResource()。
代码修改后博主又分析了项目的性能,发现Graphics这一项比之前减少了3M左右,降低到了29M。虽然仅仅是3M内存的右优化,但界面已经不在卡顿
下面是修改后的代码

 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        View view = inflater.inflate(R.layout.field_view, null, false);
                        TextView textView = view.findViewById(R.id.field_name);
                        textView.setText(mJsonList.get(i).getString("name"));
                        mRelativeLayout.addView(view);
                        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
                        layoutParams.height = (int) ((btn_row / FARM_ROW) * (farmHeight - 20));
                        layoutParams.width = (int) ((btn_column / FARM_COLUMN) * (farmWidth - 20));
                        layoutParams.topMargin = (int) (btn_y * farmHeight);
                        layoutParams.leftMargin = (int) (btn_x * farmWidth);
                        view.setLayoutParams(layoutParams);
                        view.setTag(i);
                        if (action == DRAG_EVENT) {
                            view.setOnTouchListener(moveTouchListenr);
                        } else if (action == CLICK_EVENT) {
                            view.setOnClickListener(onClickListener);
                        }

结论:
动态生成控件时,尽量避免使用setBackground()、setBackgroundResource()、setBackGroundDrawable()等一系列函数,view.getBackground()同样也会导致OOM,也要避免在java代码中过多使用,包括ImageView.setImageResource()等一系列函数也存在OOM的问题。

相关文章

  • 尽量避免在java代码中过多使用view.setBackgrou

    博主最近在开发导师的一个项目,写了一个动态生成控件的组件,这个组件的基本功能是在一个父控件中生成若干个子控件,这些...

  • 代码风格

    1.尽量避免使用数组赋值传值 2.代码中避免出现常量,如果有常量,定义const文件 3.每个class不超过10...

  • Effective Haskell

    代码中避免过多的依赖,否则这会让你的代码像命令式语言。

  • 程序设计规范

    避免'裸代码' 尽量不要直接将代码写在模块的顶层中,在执行主程序前应该总是检查 if __name__ == '_...

  • 数据库

    mysql: 优化方法: 1,sql语句的优化: 在where中尽量避免使用!= 在where中对null...

  • 解决NPE:Java8的Optional 类

    一、简述 Optional 的完整路径是 java.util.Optional,使用它是为了避免代码中的if (n...

  • 关于python工程师的面试题(一)

    一、如何提高python的运行效率?答:使用生成器;关键代码使用外部功能,针对循环的优化-尽量避免在循环中访问变量...

  • 优化android程序

    优化java代码 1.尽量使用static和final修饰符 对于一些固定的类和方法尽量使用static修饰符,调...

  • torch.jit使用时的注意事项(1)

    如果代码中有if条件控制,尽量避免使用torch.jit.trace来转换代码,因为它不能处理变化条件,如果非要用...

  • 字节流和字符流

    在操作文件流的时候尽量避免使用缓存流,非文本文件也要尽量避免使用字符流! 字节流 FileInputStream ...

网友评论

      本文标题:尽量避免在java代码中过多使用view.setBackgrou

      本文链接:https://www.haomeiwen.com/subject/kmfyrctx.html