真正的 Android 冷启动长时间白屏原因与解决方案

in 垃圾文章 | No Comments »

注:本文属于 垃圾文章补完计划

近期在 Android 开发过程中发现 App 每次启动时白屏事件特别长(大概 3s),检查了首屏 Activity 与 Application 都没发现问题,并且新建了一个空的项目问题依旧,遂谷歌之,发现一大把的文章都是介绍如何把主题的白色背景色改为透明来达到显得没有白屏。

实际产生原因是新版 Android Studio 自带的 Instant Run 功能。大概解释就是 Instant Run 为了能快速运行做了一系列操作,这部分时间就体现到了启动白屏的时间上了。

那么是否我们应该关闭 Instant Run 呢?我并不推荐,诚然在 Android Studio2.0 时代这个功能一堆 bug,连页面都没法正常渲染好,那时候毫无疑问关闭了这个功能,不过现在 Instant Run 已经改进了很多了,甚至在 Android Studio3.0 发布的时候还呼吁大家重新试试,现在的体验确实不错,缩短了很多编译时间。

那么怎么解决这个白屏时间过长的问题呢?把 apk 打包成 release 版即可。

详细介绍可以阅读郭霖大神的Android 冷启动白屏解析,带你一步步分析和解决问题。我之所以又写一篇与郭霖大神内容几乎相同的短文,是希望将来其他人遇到该问题时能得到正确的原因,而不是那漫山遍野的修改 style 方案。

记我在傻逼华为手机上遇到的坑

in 在路上 | 1 Comment »

本文内容:介绍我用傻逼华为手机调试时遇到的种种奇葩蛋疼问题
我在前司的时候,兼容性问题遇到最多的就是华为了,不过当时并没把问题记录下来,这次又换了一台华为测试机,受不了这些破问题了,怒记下来供后人参考。

华为手机不显示 log

拨号页面输入*#*#2846579#*#*,选择「1.后台设置」,「3.LOG设置」,打开「AP日志」选项。即可。

华为手机后台调试的密码是什么

如果你误以为那个「后台调试」才是显示 log 的话,恭喜你你被误导了。而这个破密码我搜了半天都没搜到!你们论坛是摆着好看的么!?那么多用户问结果没一个官方人员解决问题。

华为手机在页面有 EditText 时会闪退,报错java.lang.ref.SoftReference cannot be cast to android.view.inputmethod.InputConnection

解决办法是进入运行配置页面(运行按钮左边,点击那个 app,选「Edit Configurtions…」),选择「Profiling」选项卡,关闭「Enable advanced profiling(required for API level < 26 only)」选项。
这个功能是具体分析 App 性能的,很实用,有的人会以为这是 Android6.0 的问题,然而我自用的小米同样是6.0,并不存在这种问题。

JoJo,这是我最后的波纹了,收下它吧!——Android 波纹效果使用

in 垃圾文章 | No Comments »

本文主要内容:介绍 Android 波纹效果与兼容方式
注:本文属于 垃圾文章补完计划

在 Android App 中,触摸反馈是非常重要的,能让用户有点下去的感觉。

最简单的实现方式莫过于用户按下的时候改变背景色,例如:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <color android:color="@color/white_hover" />
    </item>
    <item>
        <color android:color="@color/white" />
    </item>
</selector>

然后直接android:background="@drawable/white_bg" 即可。

在 Android5.0后,Android 是支持了波纹效果的,视觉体验比单纯改变背景色好,使用起来也很简单,android:background="?attr/selectableItemBackground" 即可。但是问题在于它是没背景色的,难道还得再加一层 FrameLayout 不成?并不需要,直接加一个 drawable 即可:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="0dp"/>
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

这样便是一个白底的波纹背景了,需要的话也可设置圆角之类的。

但是,该方式在 Android6.0 上会有渲染 bug,加载的第一个用该背景的控件波纹是不会生效的。因此查了下 API,发现提供了更科学的波纹方式,在 drawable-21 中添加:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/white_hover"
    >
    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white"/>
    <item android:drawable="@color/white"/>
</ripple>

这样兼容性就彻底没问题了。

Android 数据通信:从基本的Activity、Fragment、Service数据传递到EventBus的使用

in 垃圾文章 | No Comments »

本文主要内容:首先介绍 Android 自带的 Activity 互相传递数据、Activity 与 Fragment 互相传递数据、Activity 与 Service 互相传递数据。随后分析它们的使用场景与优缺点,引出 EventBus,最后介绍 EventBus 的基本使用。
注:本文 Demo 皆为 kotlin 编写,有 Java 基础的读者应该能大致理解,请放心阅读。
注2:本文属于垃圾文章补完计划

Android 自带的数据通信机制

Activity 与 Activity 互相传递数据

我们将从 AActivity 启动 BActivity,并通过 intent 传送数据。
AActivity 的 onCreate 方法内:

            into_b.setOnClickListener {
            val intent = Intent(baseContext, BActivity::class.java)
            //传递基本类型
            intent.putExtra("att1", "普通的字符串")
            //传递序列化对象
            val person = Person("xloger", 18)
            intent.putExtra("att2", person)

            startActivity(intent)
        }

BActivity 的 onCreate 方法内:

        val sendMsg = intent.getStringExtra("att1")
        val person = intent.getSerializableExtra("att2") as? Person
        Log.d("XExample", "收到的消息:$sendMsg,收到的对象:$person")

输出结果:

D/XExample: 收到的消息:普通的字符串,收到的对象:Person(name=xloger, age=18)

注意,虽然 intent 看似有传 extra 和传 bundle 两种方式,但是 extra 只是 bundle 的封装。需要传递对象时需该类实现 Serializable 接口。
而当需要接收 BActivity 的返回数据时,需将原先的startActivity(intent)改为startActivityForResult(intent,233),其中整型233为 requestCode,作用是区分不同请求。
而 BActivity 在销毁前通过以下代码即可传递数据给 AActivity:

        val resultIntent = Intent()
        resultIntent.putExtra("resultMsg", "返回的内容")
        setResult(124, resultIntent)

然后在 AActivity 类中实现以下方法:

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 233 && resultCode == 124) {
            Log.d("XExample", "返回的内容为:${data?.getStringExtra("resultMsg")}")
        }
    }

当进入 BActivity 后返回 AActivity,输出结果:

D/XExample: 返回的内容为:返回的内容

注意,requsetCode 与 resultCode 目的是为了区分不同的请求。而实际开发中,这些数应该统一放入常量池中,防止数据过多时不好区分。

(更多…)

垃圾文章补完计划

in 垃圾文章 | 2 Comments »

我对我技术类文章要求还是比较严格的,我个人觉得某个问题是我在努力通过搜索引擎并没有轻易地解决,当我经历了一些波折才解决,把这样的经历写下来才是比较有价值的文章。那些一搜一大把还都是复制来复制去的“技术文章”我真的很抵触。

但是呢,在最近面试时经历了一些事,看来我被某个喜欢“写废话”的竞争者打败了=。= 因此我便自暴自弃知耻后勇地决定把一些我觉得对整个互联网并没价值的个人经验写出来了。(因为对应的知识已经有很多文章写的比我好了)

因此我把它自嘲为“垃圾文章补完计划”,虽然说是垃圾,但是并不代表质量低劣(也许呢…),文章我都是认真写的,也尽可能写的比较完善。假如身为读者的你恰好看到了,不妨读读看吧。

以及,高中毕业后便感觉我的精准表达能力在不断下降,很多内容我已经没法用书面语准确简练讲清楚了,直到某次我看到一篇阐述网络词汇广泛流行的弊端有哪些?的文章才惊醒。因此多写文章还有一个目的就是锻炼精准表达能力吧。

就像张佳玮说的,当某天我看到一个很美的景色时,我脑海里能浮现的是“落霞与孤鹜齐飞,秋水共长天一色”这样的句子,还是只能一句“卧槽,真好看”。——让孩子背诵古诗词、古文有什么意义?

© 2018 一隅 - Powered by Wordpress / Theme: Tabinikki