什么是过度绘制
然后随着UI对象不断升级,渲染流程也变得越来越复杂,列如说绘制图像,就是把图片上传到CPU存储器然后传递到GPU中进行渲染,路径使用是完全另外一码事,你需要在GPU中创建一系列的多边形,甚至在GPU中创建掩蔽纹理来定义路径。绘制字符更加复杂一些,首先我们需要在CPU中把字符绘制争图像,然后把图像上传到GPU进行渲染再返回到CPU,在屏幕上为字符串的每个字符绘制一个正方形,现在android系统已经解决了大多数性能问题,除非你还有更高要求,你基本不会发现与GPU相关的问题,然而还有一个GPU性能问题瓶颈,这个问题困扰着每个程序开发员。这就是过度绘制,你的应用程序会因为过度绘制,从而导致性能问题,如果你想兼顾高性能和完美的设计,往往会碰到一种性能问题,即,过度绘制,多度绘制是一个术语
Android提供了Ui过度绘制检测工具,在手机的开发者模式中
打开–>设置 –>开发者模式 –>GPU过度绘制选项—>显示GPU过度绘制
显示GPU过度绘制过度绘制后手机会出现不同颜色:
红色:代表4倍的绘制
粉色:代表3倍的绘制
绿色:代表2倍的绘制
绿色:代表1倍的绘制
下面是官方DEMO过度绘制的例子
Activity中加人一个fragment
public class ChatumLatinumActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatum_latinum);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_chatum_latinum_container, new ChatsFragment())
.commit();
}
}
fragment中代码
public class ChatsFragment extends Fragment {
protected static int MILLISECONDS_PER_SECOND = 1000;
protected static int SECONDS_PER_MINUTE = 60;
public ChatsFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Create a list of chats and populate it with hardcoded data.
ArrayList<Chat> chats = new ArrayList<Chat>();
populateChats(chats);
// Create the adapter that provides values to the UI Widgets.
ChatAdapter adapter = new ChatAdapter(getActivity(), chats);
View rootView = inflater.inflate(R.layout.fragment_chats, container, false);
// Find the ListView that holds all the chat messages and attach it to the adapter,
ListView listView = (ListView) rootView.findViewById(R.id.listview_chats);
listView.setAdapter(adapter);
return rootView;
}
private Date getTimeInPast(int minutesAgo) {
return new Date(new Date().getTime() -
(minutesAgo * SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND));
}
// Creates hardcoded chat objects.
private void populateChats(ArrayList<Chat> chats) {
Resources res = getResources();
Droid alex = new Droid("alex", res.getColor(R.color.alex_color));
Droid joanna = new Droid("joanna", res.getColor(R.color.joanna_color), R.drawable.joanna);
Droid shailen = new Droid("shailen", res.getColor(R.color.shailen_color),
R.drawable.shailen);
}
}
fragment是一个显示列表
我们想下activity中包含了一个fragment,就相当于fragment是activity的子布局,也就是说两个布局都需要绘制,但是我们只需要显示fragment中数据即可。那么解决办法是什么那?,我们在activity中创建fragment同时将activity布局设置为null,这样就避免了我们绘制fragment的同时也重复的绘制了activity。
优化代码
public class ChatumLatinumActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatum_latinum);
// The Theme's windowBackground is masked by the opaque background of the activity, and
// the windowBackground causes an unnecessary overdraw. Nullifying the windowBackground
// removes that overdraw.
getWindow().setBackgroundDrawable(null);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_chatum_latinum_container, new ChatsFragment())
.commit();
}
}