美文网首页
新闻类App (MVP + RxJava + Retrofit+

新闻类App (MVP + RxJava + Retrofit+

作者: Peakmain | 来源:发表于2019-04-28 10:47 被阅读0次

    Github地址:新闻类App (MVP + RxJava + Retrofit+Dagger+ARouter)

    列表页卡顿优化

    常规方案

    • convertView复用, 使用ViewHolder
    • 耗时任务异步处理

    布局相关

    • 减少布局层级,避免过度绘制
    • 异步inflate或者X2C

    图片相关

    • 避免过大尺寸:GC频繁,内存抖动
    • 滑动时取消加载

    线程相关

    • 使用线程池收敛线程,j降低线程优先级
    • 避免UI线程时间片被抢占

    TextView优化

    • 原因:面对复杂文本性能不佳
    • 原理:
      Boringlayout单行,StaticLayout多行
      DynamicLayout可编辑
    • 展示类StaticLayout即可,性能优于DynamicLayout
    • 异步创建StaticLayout
    • 代码(项目中不可直接使用)
    @Deprecated
    public class CustomTextView extends View {
        private String text="测试StaticLayout";
        private TextPaint mTextPaint;
        private StaticLayout mStaticLayout;
        public CustomTextView(Context context) {
            this(context,null);
        }
    
        public CustomTextView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public CustomTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initLableView();
        }
    
        private void initLableView() {
            mTextPaint=new TextPaint();
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextSize(16*getResources().getDisplayMetrics().densityDpi);
            mTextPaint.setColor(Color.BLACK);
            int width= (int) mTextPaint.measureText(text);
            Executors.newSingleThreadExecutor().execute(new Runnable() {
                @Override
                public void run() {
                    mStaticLayout = new StaticLayout(text, mTextPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
                    postInvalidate();
                }
            });
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(mStaticLayout != null){
                canvas.save();
                canvas.translate(getPaddingLeft(), getPaddingTop());
                mStaticLayout.draw(canvas);
                canvas.restore();
            }
        }
    }
    

    其它

    • sysTrace跟踪
    • 注意字符串拼接,最好是用StringBuilder

    存储优化

    常规方案

    • 确保IO操作发生在非主线程
    • Hook或者是AOP辅助

    SharePreference相关

    • 加载慢:初始化加载整个文件
    • 全量写入:单次改动都会导致整体写入
    • 卡顿:补偿策略导致
    • 不支持跨进程通信

    SharePreference替代者MMKV

     implementation 'com.tencent:mmkv:1.0.19'
    
    • 代码
            MMKV.initialize(this);
            MMKV.defaultMMKV().encode("times",100);
            MMKV.defaultMMKV().decodeInt("times");
    
    

    日志存储优化

    • 大量服务需要日志库支持

    • 对于性能的要求:不影响性能,日志不丢失,安全

    • 常规实现
      没产生一个日志,写一遍到磁盘中:不丢失,性能损耗
      开辟一个内存buffer,先存buffer,再存文件:丢日志

    • mmap
      内存映射文件
      优势:高性能,不丢失
      推荐库:Xlog,Logan

    • 常用数据的缓存,避免多次读取

    • 合理选择缓冲区Buffer大小, 4-8kb

    WebView异常监控

    推荐库:https://github.com/Tencent/VasSonic

    • 监控屏幕是否白屏,白屏则WebView有问题
    • 确认是白屏,所有像素一致认为白屏
    • 代码:webview白屏检测
    public class BlankDetect {
    
        /**
         * 判断Bitmap是否都是一个颜色
         */
        public static boolean isBlank(View view) {
            Bitmap bitmap = getBitmapFromView(view);
    
            if (bitmap == null) {
                return true;
            }
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            if (width > 0 && height > 0) {
                int originPix = bitmap.getPixel(0, 0);
                int[] target = new int[width];
                Arrays.fill(target, originPix);
                int[] source = new int[width];
                boolean isWhiteScreen = true;
                for (int col = 0; col < height; col++) {
                    bitmap.getPixels(source, 0, width, 0, col, width, 1);
                    if (!Arrays.equals(target, source)) {
                        isWhiteScreen = false;
                        break;
                    }
                }
                return isWhiteScreen;
            }
            return false;
        }
    
        /**
         * 从View获取转换到的Bitmap
         */
        private static Bitmap getBitmapFromView(View view){
            Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            if (Build.VERSION.SDK_INT >= 11) {
                view.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(view.getHeight(), View.MeasureSpec.EXACTLY));
                view.layout((int) view.getX(), (int) view.getY(), (int) view.getX() + view.getMeasuredWidth(), (int) view.getY() + view.getMeasuredHeight());
            } else {
                view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
            }
            view.draw(canvas);
            return bitmap;
        }
    }
    

    相关文章

      网友评论

          本文标题:新闻类App (MVP + RxJava + Retrofit+

          本文链接:https://www.haomeiwen.com/subject/zibrnqtx.html