Android应用优化(1)窗口背景

从本篇开始,我将在开发中遇到的应用优化问题进行一点经验的分享。

在UI开发中渲染这个概念相信大家都不陌生,这是优化UI的重点,Android系统支持的硬件加速就是对渲染模型的一个优化。可是不使用这个我们在软件渲染时也有一些小技巧来进行优化。

今天要说的很简单--窗口背景
在开发Activity组件时一般都会给当前的Layout设置背景的,其实这里的Window也是有背景的,如果Layout的背景不透明,那么窗口的背景对用户来说是不可见的,但是在软件渲染模型中只要子View发生变化都会引起父View的重绘,所以这里会有一定的性能影响。对于这种情况,需要将窗口背景设置为空。

采用什么方式来设置呢,有几种方法,在Activity中getWindow().setBackgroundDrawable() 来进行设置,或者通过Theme来进行修改。个人认为通过Theme来进行设置性能最优。

这里有两点需要说明一下,一是窗口背景到底是谁的背景,还有是Theme是什么时候用上的。
1、窗口背景是view树的根也就是常说的DecorView的背景图,这点从源码中可以很清楚的看到,看
phonewindow的setBackgroundDrawable的方法,    
public final void setBackgroundDrawable(Drawable drawable) {
        if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
            mBackgroundResource = 0;
            mBackgroundDrawable = drawable;
            if (mDecor != null) {
                mDecor.setWindowBackground(drawable);
            }
        }
}


其实最后就是设置的mDecor的背景图片
2、Theme是什么时候使用的,来看看phonewindow的setContentView方法就清楚了
public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (mContentParent == null) {
            installDecor();
        } else {
            mContentParent.removeAllViews();
        }
        mContentParent.addView(view, params);
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
}

    private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
            ………………
}
}

    protected ViewGroup generateLayout(DecorView decor) {
        // Apply data from current theme.
        TypedArray a = getWindowStyle();
        …………………..
        View in = mLayoutInflater.inflate(layoutResource, null);
        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));

        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        …………………….
        return contentParent;
}

    public final TypedArray getWindowStyle() {
        synchronized (this) {
            if (mWindowStyle == null) {
                mWindowStyle = mContext.obtainStyledAttributes(
                        com.android.internal.R.styleable.Window);
            }
            return mWindowStyle;
        }
    }

    public final TypedArray obtainStyledAttributes(
            int[] attrs) {
        return getTheme().obtainStyledAttributes(attrs);
    }


很清晰的思路,就不用多说了。需要注意的一点是,由于Theme是在setContentView的时候生效的,所以在代码设置Activity的theme时需要在这个操作之前才可以体现出效果来。
这里面还顺便提两点:
(1)    mContentParent,它是generateLayout中创建的,是activity中用户自定义布局的直接父容器,它是一个FrameLayout,这就是布局优化中FrameLayout可以使用merge标签代替的原因。
(2)    obtainStyledAttributes看这个方法名,style和theme的区别在哪里,我认为可以统一为Android上的Style,可以分为了两个方面: Theme针对窗体级别的,改变窗体样式; Style针对窗体元素级别的,改变指定控件或者Layout的样式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值