/   今日科技快讯   /
近日,国家计算机病毒中心发布了《移动APP违法违规问题及治理举措》。其中,MOMO陌陌、今日头条、京东金融、云闪付等下载量很高的应用也名列其中。
2016年至今,国家计算机病毒中心针对国内外的400多个应用发布渠道,共爬取移动应用APP总数量694万款,安全检测APP30515款,检测出恶意样本8000余款。
/   作者简介   /
本篇文章来自Jimmy-Sun的投稿,分享了实现沉浸式状态栏的方方面面,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章。
Jimmy-Sun的博客地址:
https://me.csdn.net/u013541140
/   概述   /
现在市面上绝大多数APP都实现了沉浸式状态栏的效果,该效果可以极大地提升用户的使用体验。但是,APP默认的情况下只是设定一个固定的状态栏颜色,那么就需要我们通过代码去动态修改状态栏颜色的。那么,如何去实现呢?
首先来说,从Android 4.4开始才能实现沉浸式状态栏的,所以如果您的APP也支持Android 4.4以下版本,那还需要对Android 4.4以下版本做“不支持沉浸式状态栏”处理。
那么,从Android 4.4开始,大概可以分成三个阶段来实现沉浸式状态栏:
Android4.4(API 19) - Android 5.0(API 21):这个阶段的实现方式为:通过FLAG_TRANSLUCENT_STATUS设置状态栏为透明并且为全屏模式,然后通过添加一个与StatusBar一样大小的View,将View的背景设置为要设置的颜色,从而实现沉浸式。
Android 5.0(API 21) - Android 6.0(API 23):从Android 5.0开始,加入了一个重要的属性android:statusBarColor和方法setStatusBarColor(),通过这个方法我们就可以轻松实现沉浸式状态栏。但是在Android 6.0以下版本官方不支持设置状态栏的文字和图标颜色,目前只有小米和魅族的ROM提供了支持。
Android 6.0(API 23)以上版本:其实Android 6.0以上的实现方式和Android 5.0+ 是一样的,区别是从Android 6.0开始,官方支持改变状态栏的文字和图标的颜色。
/   实现方案   /
为了实现沉浸式状态栏的效果,我们需要做一些前期工作,如下:
修改应用主题
为了更好地演示沉浸式状态栏的效果,我们修改应用的主题,使其不要显示Android默认的标题栏。 打开styles.xml文件,可以改成如下代码,并且将colorPrimary等颜色设置删掉:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"></style>

获取状态栏高度

新建一个StatusBarUtils.java文件,在里面添加一个获取状态栏高度的方法,以后我们都会用的到这个方法。之后我们的核心代码也在这个工具类里实现。代码如下:
public class StatusBarUtils {
    public static int getHeight(Context context) {
        int statusBarHeight = 0;
        try {
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
                    "android");
            if (resourceId > 0) {
                statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight;
    }

}

下面我们就按照从高版本到低版本的顺序来讲解如何更优雅地实现沉浸式状态栏。
/   Android 5.0+   /

设置状态栏颜色

在StatusBarUtils类里添加如下方法,实现设置状态栏颜色的功能:
public static void setColor(@NonNull Window window, @ColorInt int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.setStatusBarColor(color);
    }

}

修改状态栏颜色的功能其实就是对Window进行操作,而该Window可以是Activity或Dialog等持有的Window,所以我们就封装了一个传递Window的方法。 为了便于对Activity直接操作,可以再增加一个如下方法:
public static void setColor(Context context, @ColorInt int color) {
    if (context instanceof Activity) {
        setColor(((Activity) context).getWindow(), color);
    }

}

下面测试一下,新建一个Activity,将其布局背景设置为某个颜色,例如主题色,布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/colorPrimaryDark">

</LinearLayout>

在没设置状态栏颜色时,展示效果如下:
接下来在Activity的onCreate()方法里调用设置状态栏颜色的方法,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_color);
    StatusBarUtils.setColor(this, getResources().getColor(R.color.colorPrimaryDark));

}

展示效果如下:
这样状态栏和内容的颜色就可以一样啦!

设置状态栏文字颜色

下面我们把背景和状态栏颜色改成纯绿色(#00FF00),看看效果:
发现颜色好亮啊,状态栏里的文字都看不清了。在这种情况下,我们是可以将状态栏文字的颜色改成深色的,官方也仅支持设置状态栏文字和图标的深色模式和浅色模式,但是官方仅在Android 6.0以上版本提供支持。设置代码如下:
private static void setTextDark(Window window, boolean isDark) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        View decorView = window.getDecorView();
        int systemUiVisibility = decorView.getSystemUiVisibility();
        if (isDark) {
            decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        } else {
            decorView.setSystemUiVisibility(systemUiVisibility & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    }
}
同样再增加一个对Activity的支持:
public static void setTextDark(Context context, boolean isDark) {
    if (context instanceof Activity) {
        setTextDark(((Activity) context).getWindow(), isDark);
    }
}
为了能够根据状态栏背景颜色的深浅而自动设置文字的颜色,我们再新增一个判断颜色深浅的方法:
public static boolean isDarkColor(@ColorInt int color) {
    return ColorUtils.calculateLuminance(color) < 0.5;
}
然后在setColor()方法里新增一行设置状态栏文字颜色的代码,如下:
public static void setColor(@NonNull Window window, @ColorInt int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.setStatusBarColor(color);
        setTextDark(window, !isDarkColor(color));
    }
}
运行一下,就可以看到效果了:
上面是Android 6.0以上版本的实现,那么对于Android 6.0以下的手机怎么办呢?目前Android 5.0-6.0的手机只有小米MIUI和魅族Flyme系统提供了支持。小米MIUI的设置方法如下:
private static void setMIUIDark(Window window, boolean isDark) {
    try {
        Class<? extends Window> clazz = window.getClass();
        int darkModeFlag;
        Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
        Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
        darkModeFlag = field.getInt(layoutParams);
        Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
        extraFlagField.invoke(window, isDark ? darkModeFlag : 0, darkModeFlag);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
魅族Flyme的设置方法如下:
private static void setFlymeDark(Window window, boolean isDark) {
    if (window != null) {
        try {
            WindowManager.LayoutParams lp = window.getAttributes();
            Field darkFlag = WindowManager.LayoutParams.class
                    .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
            Field meizuFlags = WindowManager.LayoutParams.class
                    .getDeclaredField("meizuFlags");
            darkFlag.setAccessible(true);
            meizuFlags.setAccessible(true);
            int bit = darkFlag.getInt(null);
            int value = meizuFlags.getInt(lp);
            if (isDark) {
                value |= bit;
            } else {
                value &= ~bit;
            }
            meizuFlags.setInt(lp, value);
            window.setAttributes(lp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
然后在setTextDark()方法中添加如下代码:
private static void setTextDark(Window window, boolean isDark) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        View decorView = window.getDecorView();
        int systemUiVisibility = decorView.getSystemUiVisibility();
        if (isDark) {
            decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        } else {
            decorView.setSystemUiVisibility(systemUiVisibility & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        switch (OSUtils.getRomType()) {
            case MIUI:
                setMIUIDark(window, isDark);
                break;
            case Flyme:
                setFlymeDark(window, isDark);
                break;
            default:
        }
    }
}
Android 6.0以下运行效果同上,我就不给大家截图了。

设置状态栏透明

当我们APP的背景是一张图片时,未设置沉浸式状态栏的效果如下:
这时一般我们需要将图片顶到状态栏里,也就是整个内容布局顶到状态栏里,并设置状态栏的颜色透明,才能实现沉浸式状态栏的效果。
那么,在我们的StatusBarUtils类里添加如下代码:
public static void setTransparent(@NonNull Window window) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        window.setStatusBarColor(Color.TRANSPARENT);
    }
}
同样针对Activity,增加如下方法:
public static void setTransparent(Context context) {
    if (context instanceof Activity) {
        setTransparent(((Activity) context).getWindow());
    }
}
最后在Activity的onCreate()方法里设置一下:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_transparent);
    StatusBarUtils.setTransparent(this);
}
运行,显示效果如下:
针对这种情况,大家在实现布局时不要忘了把状态栏的高度也考虑进去。 以上就是Android 5.0以上沉浸式状态栏的实现了。
/   Android 4.4+   /
下面针对Android 4.4-5.0的手机进行实现。实现原理是将内容布局设为全屏,然后在布局的顶部添加一个和状态栏一样高度的View,将该View的背景设置成我们想要的颜色。当需要将状态栏设置纯颜色时,为了和Android 5.0以上版本保持一致,我们对内容布局的上边设置一个padding,大小为状态栏的高度。
为了能复用这个View,我们新增一个自定义的ID,在values文件夹下新建ids.xml文件,新增代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="fake_status_bar_view" type="id"/>
</resources>
然后在StatusBarUtils类里添加如下代码:
private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.fake_status_bar_view;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setColor(@NonNull Window window, @ColorInt int color,
                            boolean isTransparent) {
    Context context = window.getContext();
    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    ViewGroup decorView = (ViewGroup) window.getDecorView();
    View contentView = decorView.findViewById(android.R.id.content);
    if (contentView != null) {
        contentView.setPadding(0, isTransparent ? 0 : getHeight(context), 0, 0);
    }
    View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
    if (fakeStatusBarView != null) {
        fakeStatusBarView.setBackgroundColor(color);
        if (fakeStatusBarView.getVisibility() == View.GONE) {
            fakeStatusBarView.setVisibility(View.VISIBLE);
        }
    } else {
        // 绘制一个和状态栏一样高的矩形
        View statusBarView = new View(context);
        FrameLayout.LayoutParams layoutParams =
                new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getHeight(context));
        statusBarView.setLayoutParams(layoutParams);
        statusBarView.setBackgroundColor(color);
        statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
        decorView.addView(statusBarView);
    }
}

设置状态栏颜色
在设置纯颜色时,我们还需要将该颜色与黑色进行1:1的混合。为什么要这么设置呢?因为状态栏的文字和图标颜色默认是白色的,并且在Android 5.0以下是不能修改的,所以如果修改成较浅的颜色,就会导致状态栏文字看不清的现象,因此做一个比较暗的浮层效果更好一些。
那么将setColor()方法改成如下代码:
public static void setColor(@NonNull Window window, @ColorInt int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.setStatusBarColor(color);
        setTextDark(window, !isDarkColor(color));
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        setColor(window, ColorUtils.blendARGB(Color.TRANSPARENT, color, 0.5f), false);
    }
}
展示效果如下:

设置状态栏透明

在设置状态栏透明时,为了也能清楚地看清状态栏的文字,我们直接设置状态栏的颜色为50%透明度的黑色。
于是,修改setTransparent()方法如下:
public static void setTransparent(@NonNull Window window) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        window.setStatusBarColor(Color.TRANSPARENT);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        setColor(window, 0x80000000, true);
    }
}
展示效果如下:
这样,Android 4.4以上的手机就适配完毕了。
/   特殊场景   /
现在来针对一些特殊场景进行适配,比如启动页、刘海屏和弹窗等等。

启动页

对于启动页,一般都会把状态栏收上去,这需要适配刘海屏,否则刘海区域会显示黑的一片。其实Android P以上提供了适配刘海屏的方法,在启动页Activity添加如下代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    StatusBarUtils.setTransparent(this);
    // 适配刘海屏
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
        layoutParams.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().setAttributes(layoutParams);
    }
}
但是一些手机厂商的刘海屏手机系统版本是低于Android P的,不过也都提供了适配的方法。适配方式是在AndroidManifest.xml文件里的application标签下添加如下代码:
<!-- 允许绘制到小米刘海屏机型的刘海区域 -->
<meta-data
    android:name="notch.config"
    android:value="portrait" />
<!-- 允许绘制到华为刘海屏机型的刘海区域 -->
<meta-data
    android:name="android.notch_support"
    android:value="true" />
<!-- 允许绘制到oppo、vivo刘海屏机型的刘海区域 -->
<meta-data
    android:name="android.max_aspect"
    android:value="2.2" />
另外,对于Android 5.0以下的手机,适配完刘海屏后会在顶部多一块黑色半透明的View,那我们将其改成全透明的,修改onCreate()方法如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    StatusBarUtils.setTransparent(this);
    // 适配刘海屏
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
        layoutParams.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().setAttributes(layoutParams);
    }
    // 适配Android 4.4
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        StatusBarUtils.setColor(getWindow(), Color.TRANSPARENT, true);
    }
}
这样,启动页的效果就适配好了,效果如下:

弹窗

对于弹窗,只有全屏弹窗才能修改状态栏文字的颜色。详见:
https://jimmysun.blog.csdn.net/article/details/88892557
/   总结   /
以上就是全部代码了,同时我也放在GitHub上了,详见:
https://github.com/jimmysuncpt/ImmersionStatusBar
推荐阅读:
欢迎关注我的公众号
学习技术或投稿

长按上图,识别图中二维码即可关注

从0到1优雅实现沉浸式状态栏相关推荐

  1. 状态栏总结(沉浸式状态栏+状态栏颜色+状态栏字体的颜色)

    今天总结一下状态栏的使用,当然也是参考别人的.但是总归自己得试试,然后把常用的几种情况记下来,因为这些东西是死的,下次拿过来就可以用. 一. 沉浸式状态栏  :Android 5.0以上才会支持沉浸式 ...

  2. Android 5.0新特性之沉浸式状态栏

    参考资料: http://laobie.github.io/android/2016/03/27/statusbar-util.html http://laobie.github.io/android ...

  3. android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)

    Android沉浸式状态栏(5.0以上系统) 沉浸式状态栏可以分为两种: 1.直接给状态栏设置颜色 (如下图:) 这里写图片描述 java代码形式: if (Build.VERSION.SDK_INT ...

  4. Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果)

    根据需求实现类似QQ侧滑效果,之前看到过很多实现方式通过SlidingMenu,但是既然官方推出了自己的专属控件,那么使用DrawerLayout就是不二选择.且看下文. 一.先来看看官方文档解释 D ...

  5. android -------- 沉浸式状态栏ImmersionBar3.0

    沉浸式状态栏我一直在使用的 一个库 ImmersionBar,非常不错,现在都3.0了 android 4.4以上沉浸式状态栏和沉浸式导航栏管理,适配横竖屏切换.刘海屏.软键盘弹出等问题,可以修改状态 ...

  6. Android 沉浸式状态栏(QQ5.0透明状态栏的效果)

    大家注意一个问题: 魅族4.4系统,如果增加沉浸式状态栏,页面底部如果有按钮可能会被魅族的smbar遮挡,导致按钮不能被点击到的现象 看上面的这张图就是,魅族smatbar被隐藏后,挡住底部按钮,并且 ...

  7. Android 9.0 10.0 沉浸式状态栏导致导航栏状态栏灰色蒙层的解决方案

    1.概述 在10.0的系统产品开发中,在app开发中,沉浸式状态栏也是常有的样式,但是设置沉浸式状态栏后,会导致状态栏和导航栏会有灰色蒙层的问题存在 解决方案: DecorView是整个Window界 ...

  8. android 9.0去掉状态栏,安卓9.0沉浸式状态栏

    首先我们来了解一下几个设置沉浸式状态栏的基础属性: 1.View.SYSTEM_UI_FLAG_LOW_PROFILE:低调模式, 会隐藏不重要的状态栏图标: 2.View.SYSTEM_UI_FLA ...

  9. Android 沉浸式状态栏的实现方法、状态栏透明

    现在越来越多的软件都开始使用沉浸式状态栏了,下面总结一下沉浸式状态栏的两种使用方法 注意!沉浸式状态栏只支持安卓4.4及以上的版本 状态栏:4.4上是渐变色,5.0上是完全透明,本文模拟器为4.4演示 ...

最新文章

  1. 成为多编程语言人才的诀窍你想知道吗
  2. python3 获取异常类型
  3. 数论初步——同余与模算术
  4. 【PySpark入门】手把手实现PySpark机器学习项目-回归算法
  5. mysql 报错1045 - Access denied for user “root” @ 192.111.111.11 (using password: YES)
  6. 多层陶瓷电容器用处_【科普】片状多层陶瓷电容器的封装方法,你了解吗?
  7. 60-140-046-使用-DataSink-Flink写入到MySQL的2中方式
  8. github上成员贡献量_Bifrost 长期贡献规则,获得 BNC 的 5 种方式
  9. POJ1521 LA2088 HDU1053 ZOJ1117 Entropy【哈夫曼编码】
  10. eclipse中html设置,无法在eclipse中设置HTMLUNIT
  11. linux挂载曙光存储,曙光I1620G30获取设备的cpu、内存、存储等参数信息。
  12. 射频电路设计及PCB设计要点
  13. 基于微信小程序的美容美发技师预约系统设计与实现毕业设计毕设开题报告
  14. 论文笔记——多源融合SLAM的现状与挑战
  15. Linux的内核态与用户态
  16. 微信小程序实践——实验1获取用户信息
  17. 现代战争——僵尸网络的历史 上篇
  18. 28岁大爷都能看懂261页前端面试题宝典
  19. Mybatis学习 association关联 和 collection集合
  20. vue3 不推荐使用index作为v-for遍历的key

热门文章

  1. 施瓦辛格驾豪车“约会”史泰龙 老友相见相谈甚欢
  2. arduino下不用定时器的TCS3200颜色传感器
  3. c语言三种方法求n的k次方
  4. java bigdecimal 开方,Java中BigDecimal的平方根
  5. OpenCV函数学习:cvRound,cvFloor,cvCeil
  6. 虚拟变量的方法介绍及python实现方式
  7. 常用 Maven 仓库地址
  8. 05 数据库入门学习-正则表达式、用户管理、pymysql模块
  9. 神经网络训练loss不下降原因集合
  10. Android高工:okhttp原理详解,搞懂了直接去虐面试官