有没有人看过或编译过比较在Android中使用声明式(XML)和程序式创建UI的基准测试?
虽然谷歌已经采取了一些措施来加速声明式方法,但在运行时仍然需要完成布局膨胀步骤。
您是否曾考虑过将UI从声明式更改为程序式,或因任何原因进行过转换?
有没有人看过或编译过比较在Android中使用声明式(XML)和程序式创建UI的基准测试?
虽然谷歌已经采取了一些措施来加速声明式方法,但在运行时仍然需要完成布局膨胀步骤。
您是否曾考虑过将UI从声明式更改为程序式,或因任何原因进行过转换?
很少有布局膨胀是在运行时完成的。如LayoutInflator API文档所示:
出于性能原因,视图膨胀严重依赖于在构建时对XML文件进行的预处理。因此,目前不可能在运行时使用XmlPullParser覆盖普通的XML文件来使用LayoutInflater。
如果您查看source,您会发现许多视图都是根据它们的XML标记从哈希映射中获取的。
回答您的问题,我必须说没有对充气机进行基准测试。就个人而言,我认为为您的应用程序基准测试Android中的布局充气机相当于为您的网站在Firefox中基准测试DOM解析器。我不认为这种练习是毫无意义的,但是您应该有一个比“我的活动布局对充气机太复杂”更好的理由...
如果您需要动态生成布局,则最好通过编程方式创建它。如果您的视图仅花费了很长时间来膨胀,则应简化视图XML。
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);
}
}
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);
}
}