调用ViewRootImpl里的成员方法setDrawDuringWindowsAnimating--反射调用,在onAttachedToWindow或者任何view的onMeasure方法中(API19以上)
try {
getWindow().getDecorView().getParent().getClass().getMethod("setDrawDuringWindowsAnimating", boolean.class).
invoke(getWindow().getDecorView().getParent(), false);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}try {
getWindow().getDecorView().getParent().getClass().getMethod("setDrawDuringWindowsAnimating", boolean.class).
invoke(getWindow().getDecorView().getParent(), true);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}private boolean sInited = false;
private Method msetDrawDuringWindowsAnimatingMethod;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
Object viewRootImpl = ((Activity)getContext()).getWindow().getDecorView().getParent();
if (!sInited) {
try {
msetDrawDuringWindowsAnimatingMethod = viewRootImpl.getClass().getMethod("setDrawDuringWindowsAnimating", boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
if (msetDrawDuringWindowsAnimatingMethod != null) {
try {
msetDrawDuringWindowsAnimatingMethod.invoke(viewRootImpl, true);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
sInited = true;
}
}
}
只有View被添加到View树上的时候才可能会绘制,刚inflate出来的View没有被添加到View树上,所以不会进行measure和layout。measure是耗时的,如果在线程中执行,它就会减少主线程的卡顿,最后再添加到View树上,并且不用触发requestLayout。(Fragment也可以先在子线程创建,然后再UI线程添加)

总结:如果创建的View比较耗时,那么就在子线程去创建,例如上面代码,measure、layout都在子线程,然后在主线程去添加该View。 实例:如果列表数据需要从网络加载,且数据比较多,那么View加载相对较慢,则可以把列表的所有子View添加到子线程去创建,然后添加到列表中刷新。
android系统提供的GPU柱状图并不准确,无法准确的得出帧率,就利用Looper的log机制和添加全局控件来自己实现那个柱状图。
getMainLooper().setMessageLogging(new Printer() {
@Override
public void println(String x) {
if(x.startsWith(">>>>> Dispatching to Handler(android.view.Choreographer$FrameHandler)")){
long time1 = System.nanoTime();
LOG.I("Frame", "帧间隔为: " + (1000000000/(time1 - time)));
time = time1;
}
}
});WindowManager.LayoutParams.TYPE_APPLICATION可以绕过悬浮窗权限问题,直接弹出悬浮窗。
抓取手机对应型号的权限设置界面进行跳转,引导用户打开权限。
Can't convert value at index 15 to dimension: type=0x1报错原因:xml中的view尺寸没有默认值,在默认的dimens中添加一个默认值就行了。
不同进程中的A,B为两个Activity,都继承AppCompatActivity,A直接调用startActivity和调用startActivityForResult出现了不同的反应,就是后者不会在最近应用中留两个界面,而前者会
