- 博客(43)
- 收藏
- 关注
原创 MediaPlayer 播放视频出现上一帧图像问题处理
但是有时候部分视频格式支持有问题,导致只能输出音频流,没有视频帧输出,就会出现问题。因为这时候 surface 上的图像是上一个视频文件的,但其实播放的是现在的视频文件。MediaPlayer + SurfaceView 播放视频的时候,播放下一个视频时 surface 会停留在上一帧图像,正常播放情况无影响,因为马上新的视频帧就会输出上去。现在发现不少问题都是这样,并不能从根本上去解决,但是从发现方用户方入手,从体验上解决这个问题,这也不失为一个好的解决思路。,视频开始播放且有视频帧时隐藏这个界面。
2024-03-29 21:39:23
369
原创 鸿蒙开发学习入门教程之环境配置
最近鸿蒙开发越来越火,各个大厂都有鸿蒙版本的计划和宣传,看这个趋势,可能会在几年内发展壮大,为我们移动端码农开辟一片新的职场。鸿蒙开发使用的 IDE 是 HUAWEI DevEco Studio,也是基于 JetBrains 产品打造的,所以界面上看起来十分熟悉。首先,找到官方文档的入门教程,都会有第一个 demo 应用,可以跟着这个应用来配置环境并熟悉基本的开发概念。至此我们就完成了鸿蒙开发的环境配置,具体的开发讲解可以参考上面的官方网站,后续章节我也会继续分享的。其余的依赖下载都会比较快了。
2024-03-10 23:49:20
322
原创 ExoPlayer 播放视频黑屏的解决方法
但是有一点需要注意,文章里面使用的 ExoPlayer 现在(2024.3.3)google 已经迁移了这个项目到 androidx.media3 这个项目里了,所以编译时需要注意看一下代码中使用的版本是什么。下面代码就是使用方法,注释掉的是 exoplayer 2 的使用方式,剩下的是 media3 的方式。最近项目中在使用 ExoPlayer 来进行视频的播放,开发过程中遇到了部分视频打开后黑屏的问题,报错日志如下。官方文档里面也都是推荐使用 media3 了,毕竟后续的更新维护都会在这个项目上进行。
2024-03-03 22:31:46
1772
原创 Android Handler 机制解析
在 Android 开发中,Handler 的机制和运行原理这方面的知识可以说是每个人都需要熟悉的。这不仅是因为 Handler 是 Android 应用的基石之一,也因为 Handler 整体设计上也是十分优秀的。接下来我就梳理总结一下常见的 Handler 相关知识点。到这里基本梳理了 Handler 的一些使用和原理,虽然各种框架和 Kotlin 都可以很方便的执行切换线程的操作了,但是这些原理性的东西还是值得我们学习并了解的。
2023-09-05 23:05:26
822
原创 Android 工程师需要了解的 Lint 知识入门篇
前言项目开发过程中,通过对代码规范的约束对于代码质量的提升是非常重要的。这其中除了人为的代码审查之外,我们还可以使用 lint 工具来定位并修改一些有问题的代码,帮助提高我们的代码规范程度。今天我们就一起来学学 lint 的使用。自动提示Android Studio 内置了很多常用的 lint 规则,我们在平时中都能使用到。比如我们直接调用一些可能引发空指针的方法,就会出现如下图中的提示。我们平时开发过程中需要关注到这些提示并进行对应的修改。手动调用除了自动提示,我们还可以在 Android S
2021-12-13 23:29:25
1775
原创 谷歌官方推荐的安卓数据库框架 Room 使用详解(二)
在第一篇中我们介绍了基本的使用,包括表的定义、DAO 的定义和使用、简单查询和添加的操作。接着这一篇我们继续看room 在使用过程中的更多操作方法。常用的操作数据方法插入上一节中我们的user 中定义有uid 作为主键,在项目中,这个uid 是后台出参,对于每一个用户都是相同的,这时候如果我们直接插入数据这条数据就会报错,因为主键相同。我们可以试一下。android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed
2021-11-22 23:44:44
2327
原创 甲方四个字,让我看了一圈 Android PMS 源码
背景这几天有一个拍照的需求,只需要简单的调用相机拍照就可以,直接通过intent 就可以完成。但是如果手机安装了多个相机时,会弹窗提示用户选择使用哪个相机,对于这一点,甲方说了四个字用系统的好吧,那就干吧。通过搜索,了解到可以添加包名来限制响应我们intent,那我们只要获取系统相机的包名就可以了。接下来我们看下整个流程。调用相机拍照这里我们可以构建intent ,新建一个临时文件,通过uri 的形式提供出去,等系统相机拍照完成后就会将图片保存到我们提供的uri 中,接着我们就可以直接使用了
2021-11-17 09:44:13
473
原创 谷歌官方推荐的安卓数据库框架 Room 使用详解(一)
Room 框架是 Android 官方推出一款数据库操作框架,里面封装了对于 Sqlite 的操作,可以快速、便捷的完成相关操作。今天我们就来了解并学习下这块库的使用和原理。上手使用添加依赖我们首先添加依赖,我这里用的版本是2.3.0 ,然后在项目的build.gradle 文件内添加依赖,如果没有配置kapt 处理器还需要添加kotlin-kapt 插件。添加完成后同步即可。plugins{ //... id 'kotlin-kapt'} dependencies{
2021-11-16 14:19:29
2780
原创 要做一名专业的程序员
要做一名专业的程序员「程序员的职业素养」读书笔记一之前看过几本书,看到有共鸣的地方有时会用手机拍照记录下来,想着后面再记笔记,这一想都会没有然后了。前两天看到专栏形式,想着也可以将一些读书笔记做成专栏的形式记录下来,常读常新。那么就先通过这本「程序员的职业素养」来开始吧。什么是专业书中的第一章就是“专业主义”,专业意味着承担责任,承担自己在工作中的责任,而不是一味的逃避和推脱。做好三件事作为程序员,工作中的最主要的就是对代码的质量负责,而要想保证代码的质量,我们又必须做好三件事情,分别是测试
2021-09-11 16:00:02
105
原创 LiveData 源码解析
简单介绍LiveData 是一个基于观察者模式的组件,在 Android JetPack 组件中的一部分,在开发中非常实用。LiveData 就是一个数据持有类,可以分发数据,由于内部封装了生命周期回调,所以只会在适当的生命周期中回调数据,而不会在监听者销毁后回调而导致异常。下面我们就用一个简单的例子来分析一下 LiveData 的源码吧。相同页面传值我们首先在onCreate方法中进行监听,通过点击按钮改变数据,可以看到,每次改变数据后我们的回调都会打印。LiveDataTest.getLive
2021-08-31 22:47:21
159
原创 学点什么之 startActivityForResult 的新用法
简单介绍startActivityForResult 是用来启动另一个 activity 后接收回调的,这个方法在 activity 和 fragment 里面都可以调用。使用后在调用者的 onActivityResult 里面进行返回参数的处理即可。这样不可避免导致了调用逻辑和处理逻辑的分离,为我们代码的可阅读性增加了几分难度。Android 官方应该也是注意到了这个问题,在 AndroidX 中为我们提供了 Activity Result API 功能,封装了 startActivityForRes
2021-08-25 23:28:12
627
原创 程序员常用的 Android App 更新中
手机管理类MT 管理器双栏模式管理手机文件https://www.coolapk.com/apk/bin.mt.plusSendApp分享手机上面已安装软件https://www.coolapk.com/apk/io.github.skyhacker2.sendapp二维码扫描简单使用,方便小巧的二维码扫描工具https://www.coolapk.com/apk/mark.qrcode应用签名信息查看手机已安装软件的包名、版本号、签名等信息https://www.co
2021-08-08 13:31:01
1129
4
原创 Android 开发中实体类命名总结
Entity数据表对应到实体类的映射,包括 room 数据库等数据。Model展示在 view 层的数据,展示在页面的数据,包括 viewmodel 里面使用的。DTO数据传输对象 Data Transfer Object用于系统建数据传输的对象,数据传输目标往往是数据访问对象从数据库中检索数据。网络请求的数据等,包括出入参等信息。Bean对于 Bean 而言,只要是 Java 的类就可以称为一个 Bean它不仅仅可以包括对象的属性以及 get set 方法,还可以有具体的业务逻辑。其
2021-08-04 10:21:32
494
原创 快速入门 Kotlin 的扩展函数
fun User.validateBeforeSave() { fun validate(value: String, fieldName: String) { if (value.isEmpty()) { throw IllegalArgumentException("Can't save user ${id}:empty $fieldName") } } validate(name, "Name") validate
2021-05-23 11:21:15
249
原创 谷歌官方新推出的 RecyclerView ConcatAdapter 使用教程
本文同步发表于我的微信公众号,在微信搜索 不要注水 即可关注。谷歌官方新推出的 RecyclerView ConcatAdapter 使用教程ConcatAdapter 可以连接多个不同的 Adapter 并做展示,但是不支持不同的数据源混合展示。首先我们新建两个 Adapter// TextAdapterclass TextAdapter : RecyclerView.Adapter<TextAdapter.TextViewHolder>() { val textLis.
2021-05-21 12:06:22
711
原创 自定义 View 添加动画效果
自定义 View 添加动画效果今天看教程的时候看到了自定义 View 添加动画效果的方法,通过属性动画获取值,然后设置到自定义 View 中即可。部分代码如下: // 属性动画 ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 3000); valueAnimator.setDuration(1000); valueAnimator.setInterpolator(new Dec
2021-05-21 09:32:00
468
原创 在开发中快速上手 git 的常用操作
在开发中快速上手 git 的常用操作git 作为版本控制工具,可以说是开发过程中的一个利器,非常强大。但平时也只会用到一些常用的操作,今天就来一起快速上手这些操作吧。操作过程中推荐使用命令行工具还有 idea 的一个可以新建忽略文件的插件,可以到网盘下载(链接: https://pan.baidu.com/s/1w8PbO27T0B67eaKWnjjs2g 提取码: 2u4u)。首先我们用 idea 新建一个项目,在默认工程里面输入如下代码:public class Main { publi
2021-05-20 20:56:53
84
原创 不是大牛,也能分析 ButterKnife 源码流程
ButterKnife 是一个可以自动完成页面 findViewById 的工具,来自大名鼎鼎的 JakeWharton 之手。当然现在(2021.4.14)已经停止更新了,贴一下 github 上的说明:Attention: This tool is now deprecated. Please switch to view binding. Existing versions will continue to work, obviously, but only critical bug fixes
2021-04-14 19:38:00
83
原创 不是大牛,也能分析 AsyncTask 源码流程
这几天在看一些教程,说到了源码分析的方法,其中之一就是不要纠结于每一行代码到底代表什么,而是要先搞清楚主要流程并学习里面的设计思想。并带着分析了一下 AsyncTask 的源码。分析之后确实感觉受益匪浅,虽然里面一些线程的知识并不了解,但是对整体设计和流程有了一个新的认识。所以为了分享下学到的东西,就记录一边,希望大家也能有所收获。注意 AsyncTask 在 SDK30 及以上已经被弃用,在开发中并不推荐使用了。首先,新建一个 AsyncTask 后,实现具体的方法,调用 execute() 方法
2021-04-06 18:39:37
85
原创 android 监听 app 启动和退出
最近有一个需求是需要在程序每次启动的时候检测一下更新,然后做出一些提示。开始是想到在 BaseActivity 里面处理,后来搜了一些资料后发现可以使用 lifecycle 实现。话不多说上代码,首先在 application 里面添加监听方法。class BaseApplication : Application() { private val checkObserver = CheckObserver() override fun onCreate() { s
2020-10-30 18:00:36
9251
2
原创 要想进步,怎么能不学习算法呢?
数据结构和算法,从大学到现在学习了这么多年,也是一直没有学会。平时工作无非是在写业务逻辑,也用不上这些,但是想要看一些源码内容的时候,发现里面很多地方都是数据结构和算法的知识。况且数据结构和算法也是大厂面试必考。不学会,怎么行呢?所以这次我又来了,拿起购买了许久的课程,继续学起来。总共选了两份资料,第一份是视频,可以直接在 B 站看,比较偏向理论基础。第二份是极客时间的专栏,比较偏实战,有很多实际开发中的问题。资料准备好了,剩下的就是学习了。当然如果只是学习,那么一个星期后可能就忘记了,这时候就需要记
2020-05-18 00:15:03
165
原创 删除 ButterKnife 绑定过的View时候,运行报错
直接删除所有的会报错,先删除 @BindView 语句,保留ButterKnife.bind(this);然后重新编辑就可以了
2020-04-17 09:50:59
301
原创 常用的好用的软件记录
PCpdf 阅读器https://www.sumatrapdfreader.org/free-pdf-reader.html截图、取色工具https://getsharex.com/文件比对工具https://www.scootersoftware.com/download.php反编译工具 - 非常好用https://github.com/skylot/jadx/releases...
2020-03-16 09:09:03
368
原创 为 git 项目设置该项目内有效的邮箱地址和昵称
平时常用的是这样的,会设置成全局生效的 git config --global user.email "you@example.com" git config --global user.name "Your Name"如果我们只需要在项目内有效,那么则可以这样设置 git config user.email "you@example.com" git config user.name...
2020-03-16 08:37:34
426
原创 Spring Boot 配置 MyBatis 入门教程
最近在公司接触 spring boot 后台,今天记录下 Spring Boot 框架和 MyBatis 配置的记录。添加 MyBatis 依赖 <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> ...
2019-08-29 09:35:17
190
原创 抽象类构造器调用抽象方法执行顺序
现在有一个抽象类 GenericWithCreateabstract class GenericWithCreate<T> { final T element; GenericWithCreate() { System.out.println("GenericWithCreate constructor"); element = c...
2019-08-05 21:39:03
1157
原创 错误 More than one file was found with OS independent path 'META-INF/atomicfu.kotlin_module'
在项目中添加了,kotlin coroutines 后编译错误 // Coroutines api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines" api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.corou...
2019-07-28 11:59:35
928
原创 Kotlin 和 Retrofit
如果在使用 Retrofit 中使用 Kotlin 定义接收数据的实体类,那么这些实体类的字段建议设置为可空类型。如果设置为不可空类型,如果后台返回的时候是空字段,那么 Retrofit 生成的这些实体类的字段也会是空的,虽然声明为可空了。...
2019-07-18 15:22:34
235
原创 Android 开发常用的 adb 命令
查看系统 arm 版本adb shell getprop ro.product.cpu.abi卸载软件adb uninstall package name
2019-07-16 10:37:11
121
原创 Kotlin 获取随机数的两种写法
前言这里先推荐下前几天写过的 Kotlin 学习资料 ,值得阅读。今天记录下 kotlin 中获取随机数的写法,简单来说就是 java 方式,kotlin 方式。Java 方式 println(Random().nextInt(4))很简单,直接调用 java 相关方法就可以实现,这里会打印出 0 到 3 包括 3 之间的整数。如果你使用 jdk 1.7 及以上版本,推荐使用 Thr...
2019-06-23 22:48:35
41207
1
转载 Kotlin 学习资料大收集
首先肯定是官方文档啦https://kotlinlang.org/docs/reference/这里是对应的翻译http://www.liying-cn.net/kotlin/docs/reference/感谢翻译大佬们的付出,让我们的学习之路更加轻松。以及配套的 pdf 文档,方便在手机上看...
2019-06-20 14:52:55
577
原创 Android 点击两次退出最佳实践
@Override public void onBackPressed() { long currentTime = System.currentTimeMillis(); if (currentTime - lastTimeMillis <= 3000) { super.onBackPressed(); ...
2019-06-19 15:32:07
226
原创 MVP 模式中解决 NPE 问题
网上搜集到三篇文章https://www.jianshu.com/p/a46d22fe9928https://medium.com/@trionkidnapper/android-mvp-an-end-to-if-view-null-42bb6262a5d1https://blog.csdn.net/qq137722697/article/details/78275882前两篇是用动态代...
2019-06-05 15:13:39
183
原创 Kotlin 中定义数组的方式
分别有以下几种方式。 val array1 = Array(10) { i -> i * i } val array2 = IntArray(10) val array3 = arrayOfNulls<Int>(5) val array4 = intArrayOf(1, 2, 3, 4, 5)
2019-05-27 16:05:24
11808
原创 Android 中两种单例的写法
个人常用的有 DCL 和静态内部类实现的单例。分别记录一下。DCLpublic class DataHelper { private static volatile DataHelper instance; private DataHelper() { } public static DataHelper getDefault() { if (instan...
2019-04-08 10:08:47
221
原创 Android 开发中异步回调改成同步回调
前言在 Android 开发中,遇到的很多回调情况都是异步回调,比如访问网络、访问本地文件或数据库等等,在子线程中进行这些操作,然后等结果返回后,再来到主线程进行 UI 更新等动作。这也是习以为常的事情了,那么如何将这种异步回调改成同步式的回调呢,今天就来说说我所了解到的方法。基本介绍首先我们定义一个异步回调public class MyEvent { public void t...
2019-04-04 10:21:42
7634
3
原创 LayoutAnimation 实现 RecyclerView 入场动画
文章目录介绍LayoutAnimation 的具体使用1,定义 RecyclerView2,使用 LayoutAnimation 动画定义动画文件定义 LayoutAnimation使用 LayoutAnimation代码设置xml 文件形式更新数据时使用动画附从右侧滑入动画从底部进入动画参考介绍最近在学习动画相关的内容,在动画应用方面的一个常用的地方就是 RecyclerView 的入场动画...
2019-04-01 14:04:04
2506
1
原创 Android 系统的布局
文章目录前言LinearLayout 线性布局RelativeLayout 相对布局ConstraintLayout 约束布局FrameLayout 帧布局总结前言在开发过程中,第一个接触的就是布局了,最熟悉的布局文件就是 activity_main.xml 了。今天就来看看布局文件中常见的几大布局。早期官方给我们提供的布局包括:LinearLayout、FrameLayout、Absolu...
2019-03-26 10:39:24
171
原创 Fragment 基础知识记录
目录前言Fragment 的加载方式静态加载动态加载通过 FragmentAdapter 加载Fragment 的生命周期Activity 和 Fragment 对应生命周期启动时的生命周期黑屏后的生命周期亮屏后的生命周期销毁时的生命周期总结前言Fragment 在开发中一直很常用,但是忏愧的是在我的开发中到现在还没怎么大量使用。导致的结果就是在面试时候一些基础知识都忘记了。今天就将这些基础知...
2019-03-22 14:39:20
231
原创 Android Activity 学习总结第一篇
开篇语说到 Activity 首先提到的就是生命周期、启动模式、异常情况下的生命周期,这些都是比较基础而且重要的知识,需要熟练掌握。当然也是面试经常遇到的问题。接着就是整个 Activity 的启动流程了,包括启动层面的第一次进入 app 或者当初的启动一个 Activity 中的启动流程了,这都需要结合源码分析并学习。这个准备在第二篇开始学习。今天就来总结下基础部分的知识点。Activity...
2019-03-21 22:03:30
361
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人