当APP性能低下的时候,仅仅表明红色dot可能存在问题。由于这里的颜色值是一个相对值,总是会有一个最慢的节点,确保它应该是最慢的。
slow.xml文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="horizontal" >
<ImageView android:id="@+id/iv" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:contentDescription="@null" android:src="@drawable/ic_launcher" />
<LinearLayout android:id="@+id/ll_right" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="4" android:orientation="vertical" >
<TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#ff0000" android:text="This is Title!" />
<TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" android:background="#00ff00" android:text="This is Content!" />
</LinearLayout>
</LinearLayout>
MainActivity代码如下:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slow);
}
}
使用Hierarchy Viewer分析如下:
这里在强调一下这里都是相对值,单纯的看Measure/Layout/Draw没有意义。由于手机或者PC CPU负载的变化每一次获取的图片都可能不一样,可以通过点击上图的三色按钮进行刷新。这里发现id/ll_right的Measure是红色的,这里符合提到的第一条和第二条,分析一下id/ll_right的子节点, 应该很快发现,Android中不提倡使用weight,咱们这里使用了weight的嵌套,更是大忌。官方文档是这么说的
It is a common misconception that using the basic layout structures leads to the most efficient layouts.
However, each widget and layout you add to your application requires initialization, layout, and drawing.
Furthermore, ***nesting several instances of LinearLayout that use the layout_weight parameter can be especially expensive as each child needs to be measured twice.***
This is particularly important when the layout is inflated repeatedly, such as when used in a ListView or GridView.
使用layout_weight参数的多级嵌套LinearLayout,每一个孩子节点需要测量两次。
优化一下,修改一下布局参数:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="horizontal" >
<ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="match_parent" android:contentDescription="@null" android:src="@drawable/ic_launcher" />
<TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/iv" android:background="#ff0000" android:text="This is Title!" />
<TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/tv_title" android:layout_toRightOf="@id/iv" android:background="#00ff00" android:text="This is Content!" />
</RelativeLayout>
MainActivity代码如下:
package com.example.hierarchyviewdemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.improved);
final ImageView iv = (ImageView) findViewById(R.id.iv);
RelativeLayout.LayoutParams ivParams = (RelativeLayout.LayoutParams) iv
.getLayoutParams();
ivParams.width = getScreenWidth(this) / 5;
ivParams.height = RelativeLayout.LayoutParams.MATCH_PARENT;
final TextView titleView = (TextView) findViewById(R.id.tv_title);
RelativeLayout.LayoutParams titleParams = (RelativeLayout.LayoutParams) titleView
.getLayoutParams();
titleParams.width = RelativeLayout.LayoutParams.MATCH_PARENT;
titleParams.height = dip2px(this, 100) / 5;
}
public static int getScreenHeight(Activity packageContext) {
DisplayMetrics metrics = new DisplayMetrics();
packageContext.getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
return metrics.heightPixels;
}
public static int getScreenWidth(Activity packageContext) {
DisplayMetrics metrics = new DisplayMetrics();
packageContext.getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
return metrics.widthPixels;
}
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
}
看一下效果:
这里分析很粗错,仅仅起到一个抛砖引玉的作用,希望能给大家有点引导作用。
https://developer.android.com/tools/performance/hierarchy-viewer/profiling.html#InterpretingResults
http://developer.android.com/training/improving-layouts/optimizing-layout.html#Inspect