之前看了性能优化有布局优化,觉得也就是稍微减少一点点的时间,但是今天做了一个demo发现,我的天啊,只增加了10TextView 竟然就增加了140ms的时间。之前真没有想到会增加这么多。
1: 测试 增加多个TextView。(增加10个TextView 大概增加了140ms的时间。当然这个在不同的机器上面当然是不一样的。)
./adb logcat | grep Displayed
05-14 18:45:02.389 1882 1904 I ActivityManager: Displayed bjpkten.startuptimedemo/.MainActivity: +2s631ms
05-14 18:45:50.504 1882 1904 I ActivityManager: Displayed bjpkten.startuptimedemo/.MainActivity: +1s814ms
我们可以通过Systrace 来查看这个布局加载的时间,
打开ddms,点击来采集Systrace
在Systrace 的html 里面,我们搜索 inflate
点击m (mark current selection),点击f 可以focus 到这个selection
inflate 可能会涉及到很多,我们可以通过w键来进行放大当前的inflate,参看到底加载了什么
2: 测试 使用include 和 merge 来进行性能优化。使用include 和merge 可以节省10-20ms
3: 测试 使用ViewStub 来进行性能优化。懒加载,(有同事做的Chrome 浏览器,里面用到ViewStub特别多)使用ViewStub可以节省大概20ms。其实ViewStub 相当于是include, 但是呢,它并不加载进来,只有在需要的时候才加载进来,Stub 就是代理吗,
举个栗子:医院排队,我们请我们的朋友在那边帮忙排着,等时间到我们了,我们再去。ViewStub 一般就是用在这种情况的,例如网络加载的界面,只有在有网络的时候才用到,在刚进来的时候可能我们并不需要加载,那么我们就先用ViewStub 占着这个位置,等我们需要的时候再加载进来
ViewStub
相信在开发Android App的过程中,我们会常常遇到这样的业务需求,需要在运行时根据数据动态决定显示或隐藏某个View和布局。通常就是把可能用到的View先写在布局里,再初始化其可见性都设为View.GONE,然后在代码中根据数据动态的更改它的可见性。虽然这样的实现,逻辑简单而且控制起来比较灵活。但是也存在一定的缺点耗费资源,即使把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,即说仍然会创建对象,会被实例化,会被设置属性从而导致耗费内存等资源。今天推荐一种新的机制——ViewStub,但要根据自己的业务需求来灵活使用。
0: 默认的viewstub 是gone的
1: inflate 只能一次,而且第一次执行以后会自动的将viewstub 显示出来,执行第二次的时候会报错,这个需要try catch
2: viewstub 内部的布局智能通过它自己findviewbyid 出来
3: 几个参数要弄明白了, infaltedId值得是viewstub 导入的布局的根目录的id,layout 就是要导入的布局,
<ViewStub
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/main_viewstub"
android:inflatedId="@id/viewstub"
android:layout="@layout/viewstub"/>
MainActivity.java
package bjpkten.viewstubdemo;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewStub;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private ViewStub mViewStub;
private TextView mTextView;
private static int num = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewStub = (ViewStub) findViewById(R.id.main_viewstub);
// mTextView = (TextView) findViewById(R.id.text_in_viewstub);
mViewStub.setOnInflateListener(new ViewStub.OnInflateListener() {
@Override
public void onInflate(ViewStub stub, View inflated) {
//回调
Toast.makeText(MainActivity.this,"show",Toast.LENGTH_LONG).show();
}
});
}
public void show(View view) {
try {
//只能infalte 一次,同时infalte 出来以后会自动的显示出来
ConstraintLayout inflate = (ConstraintLayout)mViewStub.inflate();
//注意ViewStub 里面的布局,智能通过它自己inflate出来,不能在mainactivity的onCreate 方法里面inflate
mTextView = inflate.findViewById(R.id.text_in_viewstub);
}catch (Exception e){
e.printStackTrace();
}finally {
mViewStub.setVisibility(View.VISIBLE);
mTextView.setText("show" + num++);
}
}
public void hide(View view) {
mViewStub.setVisibility(View.GONE);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ViewStub
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/main_viewstub"
android:inflatedId="@id/viewstub"
android:layout="@layout/viewstub"/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="show"
android:onClick="show"/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="hide"
android:onClick="hide"/>
</LinearLayout>
viewstub.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/viewstub"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_in_viewstub"
android:text="I am View Stub"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
性能优化:
http://cio.it168.com/a2018/0724/3215/000003215749.shtml
https://www.cnblogs.com/xunzhi/p/5794793.html
https://developer.android.google.cn/topic/performance/vitals/launch-time
https://developer.android.google.cn/studio/command-line/systrace
https://www.jianshu.com/p/6bce4e256381
https://blog.csdn.net/lamp_zy/article/details/53375521
ViewStub:
参考:https://www.cnblogs.com/plokmju/p/android_ViewStub.html
参考:https://blog.csdn.net/crazymo_/article/details/78742884