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

来源:互联网 发布:淘宝客高佣金申请工具 编辑:程序博客网 时间:2024/05/22 15:18
从本篇开始,我将在开发中遇到的应用优化问题进行一点经验的分享。

在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
原创粉丝点击