安卓初始化页面时view的异步加载
前提条件
-
Rxjava 2
-导入io.reactivex.rxjava2:rxjava:${Version.rxjava2} -
在初始化页面时 inflate耗时较久的view
使用
1. 可以先用as的 *
Debug.startMethodTracing
和
Debug.stopMethodTracing
去检测中间代码的耗时时间;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Debug.startMethodTracing("SearchMusicActivity");
setContentView(R.layout.activity_search_music);
initView();
AsyncLoadView();
// Debug.stopMethodTracing();
}
initView()中复杂页面的加载放到 AsyncLoadView() 中 , initView()可只放整体框架界面,便于快速进入此页面(活动或碎片等);
@SuppressLint("CheckResult")
private void AsyncLoadView() {
Single.create((SingleOnSubscribe<View>) emitter -> {
View view = getLayoutInflater().inflate(R.layout.search_left, null);
// 解析xml的操作
emitter.onSuccess(view);
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(view -> {
View stub = findViewById(R.id.viewStub);
if (stub == null) return;
ViewGroup parent = (ViewGroup) stub.getParent();
// 先找到占位的View
int index = parent.indexOfChild(stub);
// 拿到属性
ViewGroup.LayoutParams vlp = stub.getLayoutParams();
// 把属性设置给新的View
view.setLayoutParams(vlp);
// 从view 树中删除
parent.removeViewAt(index);
// 把新的View加载进去
parent.addView(view, index);
initKeyBoard();
});
}
因为原来R.layout.search_left 处的布局被异步加载了,所以原来的位置用一块纯色view填充,等异步加载成功之后替换掉,并把宽高等LayoutParams属性赋给复杂view
可以给AsyncLoadView()加一个CallBack参数,便于在emitter.onSuccess(view)发送成功事件 之后,主线程订阅到相应事件时调用回调成功, 做一些其他操作