代码之家  ›  专栏  ›  技术社区  ›  Steve

android-声明式与编程式ui

  •  18
  • Steve  · 技术社区  · 14 年前

    有没有人看过或编译过比较android中声明式(xml)和编程创建的ui的基准?

    google已经做了一些事情来加速声明性方法,但是您仍然可以在运行时完成布局膨胀步骤。

    您是否曾出于任何原因将您的ui从声明式转换(或考虑)为编程式?

    3 回复  |  直到 12 年前
        1
  •  23
  •   seanhodges    12 年前

    在运行时很少进行布局膨胀。正如layoutinflator api文档中所暗示的:

    出于性能原因,请查看 通货膨胀严重依赖于 XML文件的预处理 在构建时完成。因此,它是 目前无法使用 带有XmlPullParser的LayoutFlater 在运行时在纯xml文件上

    如果你看看 source ,许多视图是基于其xml标记从散列映射中提取的。

    在回答你的问题,我是否已经基准化的充气机,我不得不说没有。我个人认为,基准化的想法布局充气机在安卓为您的应用程序相当于基准化的dom解析器在火狐为您的网站。我不认为这个练习毫无意义,但你应该有一个比“我的活动布局对充气机来说太复杂”更好的理由…

    如果您需要动态生成的布局,最好以编程方式创建它。如果您的视图只是需要很长时间来膨胀,那么您应该简化视图xml。

        2
  •  3
  •   ruhalde    13 年前

    我开发这个类是为了预先膨胀一个视图池,并在每次需要时重用它。我在更新用户界面时获得了几秒钟的性能,这非常令人印象深刻。

    我的猫说:

    updating UI inflating on demand >> 2136mS
    updating UI reusing from pool >> 937mS
    

    这是我的课程,不要介意我笨拙的Java编码风格,我是C++嵌入式程序员。

    import java.util.ArrayList;
    import java.util.List;
    import android.view.LayoutInflater;
    import android.view.View;
    
        public class ViewPool {
            private List<View> mViews;
            private LayoutInflater mInf;
            private int mIdx;
            private int mResource;
    
            /**
             * Constructor, gives Inflater and resource ID to inflate
             * @param mInf Layout inflater
             * @param rID  Resource ID of view to inflate
             * @para number number of views that must inflate on first initialization
             */
            public ViewPool(LayoutInflater mInf, int rID, int number) {
                super();
    
                int idx;
                mViews = new ArrayList<View>();
                this.mInf = mInf;
                mResource = rID;
                mIdx=0; // index of first used item
    
                for(idx=0; idx<number;++idx)
                {
                    mViews.add((View)mInf.inflate(mResource, null));
                }
    
            }
    
            /**
             * Start from first item of pool
             */
            public void Reset()
            {
                mIdx=0;
            }
    
            /**
             * Get a view from pool, if no more views on pool, inflate more 
             * @return
             */
            public View GetView()
            {
                View retval;
    
                retval = mViews.get(mIdx);
                ++mIdx;
    
                if(mIdx == mViews.size()) // no more views in pool??
                    mViews.add((View)mInf.inflate(mResource, null)); // inflate more
    
                return(retval);
            }       
        }
    
        3
  •  3
  •   Andrew Calder    12 年前

    我对此做了一些非常非正式的/黑客式的测试,发现采用编程的方法,虽然不太好用,但只节省了总时间的三分之一到一半。测试只在三星7“Galaxy上进行,而不是在AVD上进行。

    正如我所说,这是一个非常非正式的/黑客式的测试(正如您将从代码中看到的那样),在非常有限的情况下,您可以快速地组合起来满足自己的好奇心,而不是通常用于公共消费。

    r.layout.ll和r.layout.tv分别是包含空白线性布局和文本视图的简单布局文件。

    如果您只是处理一些视图,我会坚持使用xml/inflaters,但是对于数百个视图,如果速度是一个问题,那么您可能会考虑使用编程方法。

    package com.inflatervscode;
    
    import java.util.Calendar;
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class InflaterVSCodeActivity extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    // Generates a few nested LinearLayouts/TextViews, a number of
    // times, and works out how many milliseconds this took.
    @Override
    public void onResume() {
        super.onResume();
        setContentView(R.layout.main);
    
        int num_repeats = 500; // Change this to however many times you want to
                               // create a set of nested views.
        LinearLayout masterLL = (LinearLayout)findViewById(R.id.test);
        TextView results = (TextView)findViewById(R.id.results);
    
        Calendar c = Calendar.getInstance();
        long startTime = c.getTimeInMillis();
    
        for (int i=0;i<num_repeats;i++) {
                // Replace the section below with LinearLayout fll = new LinearLayout(this); etc
            LinearLayout fll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
            LinearLayout sll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
            LinearLayout tll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
            TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tv, null);
    
            tv.setText(i+"");
            tll.addView(tv);
            sll.addView(tll);
            fll.addView(sll);
            masterLL.addView(fll);
        }
    
        c = Calendar.getInstance();
        long endTime = c.getTimeInMillis();
    
        String tt = Long.toString((endTime-startTime));
    
        results.setText("Results for "+num_tests+" tests:\n\nStart:"+Long.toString(startTime)+"\nEnd  :"+Long.toString(endTime)+"\n\nDifference (ms):"+tt);
    }
    

    }