Skip to content

Latest commit

 

History

History
107 lines (89 loc) · 4.42 KB

File metadata and controls

107 lines (89 loc) · 4.42 KB

Android开发技巧

1.Activity切换动画过程中页面不加载或者只绘制几帧解决:

调用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;
            }
        }
    }

2.异步加载View--优化卡顿:

只有View被添加到View树上的时候才可能会绘制,刚inflate出来的View没有被添加到View树上,所以不会进行measure和layout。measure是耗时的,如果在线程中执行,它就会减少主线程的卡顿,最后再添加到View树上,并且不用触发requestLayout。(Fragment也可以先在子线程创建,然后再UI线程添加)

总结:如果创建的View比较耗时,那么就在子线程去创建,例如上面代码,measure、layout都在子线程,然后在主线程去添加该View。 实例:如果列表数据需要从网络加载,且数据比较多,那么View加载相对较慢,则可以把列表的所有子View添加到子线程去创建,然后添加到列表中刷新。

3.准确获取GPU柱状图

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;
        }
    }
});

4.超级权限

WindowManager.LayoutParams.TYPE_APPLICATION

可以绕过悬浮窗权限问题,直接弹出悬浮窗。

5.帮助用户打开权限

抓取手机对应型号的权限设置界面进行跳转,引导用户打开权限。

6.Android7.0设置选项中有调节显示大小,如果调整到最大会报如下错误:

Can't convert value at index 15 to dimension: type=0x1

报错原因:xml中的view尺寸没有默认值,在默认的dimens中添加一个默认值就行了。

7.多进程中启动Activity的问题

不同进程中的A,B为两个Activity,都继承AppCompatActivity,A直接调用startActivity和调用startActivityForResult出现了不同的反应,就是后者不会在最近应用中留两个界面,而前者会