
Android
文章平均质量分 89
六号表哥
这个作者很懒,什么都没留下…
展开
-
Fragment OnBackPressedDispatcher 监听Activity的onBackPressed
需求场景描述在目前的比较常见的一种场景是,在 App 的首页如果点击 back 键会 toast 提示用户再点击一次是退出 App。例如如下代码所示:# 首页Homectivity.java@Overridepublic void onBackPressed() { if ((System.currentTimeMillis() - exitTime) > 2000) { ShowUtils.toast(R.string.exit_tost);//提示再按一次back原创 2021-04-01 20:03:44 · 3550 阅读 · 3 评论 -
Gradle Plugin入门使用
# Gradle Plugin插件是一系列 Task 的组合。## 插件可以用来干嘛?模块化构建脚本的功能公共的功能可以抽取出来成为插件,可以供多个 build.gradle 使用,增加复用性。## 插件的类型脚本插件是一个构建脚本,只是将构建脚本的一部分抽取到单独的xxx.gradle 文件中,然后再通过 apply from:xxx.gradle 的方式将其引入...原创 2018-09-17 23:26:36 · 6320 阅读 · 1 评论 -
从源码的角度分析 Gradle 是如何生成 BuildConfig 类的
一、学习目标BuildConfig 类是 Gradle 自动生成的,存放在 /build/generated/source/buildConfig/debug(release)/包名/BuildConfig 因此我们需要在 Gradle 构建时来配置这个类的属性。而在开发中,我们想在 BuildConfig 中增加一个 DEBUG_LOG 属性,用来判断是否开启 log 输出日志的开关。下面我...原创 2019-02-21 22:17:34 · 1880 阅读 · 1 评论 -
SharedPreference 源码分析
一、 本节目标SharedPreference 是一个轻量级的 key-value 存储框架。开发者很容易地可以使用它的 api ,但是如果不恰当的使用可能会导致一些问题,所以针对如何使用和处理这些问题,列出了以下几个小点。1、sp 实例的获取。2、sp 是如何进行读写操作和缓存处理的?3、commit 和 apply 的区别?4、不恰当使用 sp 的一些坑。5、s...原创 2019-01-31 15:14:01 · 628 阅读 · 0 评论 -
Android 利用 FFmpeg 解码音视频数据
一、本节目标继上节获取解封装的 AvPacket 数据包之后,我们知道 AvPacket 存储的都是编码后的数据,因此我们需要将数据包进行解码,从而得到原始的数据,而 FFmpeg 使用 AvFrame 这个数据结构来存储解码后的数据。对于解码后的数据:视频原始数据一般是用 yuv 表示。音频原始数据一般用 pcm 表示。而在开始之前,我们还是来回顾一下 FFmpeg 处理流的整个过...原创 2019-01-21 00:11:39 · 1679 阅读 · 0 评论 -
Android 利用 FFmpeg 获取每一帧数据信息
一、本节目标在上一节中演示了如果打开码流并且获取音视频的相关信息。这一节来获取码流每一帧的信息。在开始之前,首先来了解一下 FFmpeg 的对码流的处理过程。FFmeg 处理流程如下:1、得到输入流,打开输入流2、解封装格式->得到编码数据包 AvPacket3、解码数据包->得到解码的原始数据 AvFrame4、处理数据->例如滤镜处理等5、编码原始数据-&...原创 2019-01-20 20:51:03 · 3328 阅读 · 0 评论 -
Android 在JNI子线程调用Java方法
1. C++ 全局调用Java方法之前讨论过,如何C++主线程中调用 Java 函数C++主线程调用Java方法,下面来看看如何在子线程中调用 Java 函数。由于JNIEnv是与线程绑定的,就像 Android 的 Looper 也是和线程绑定一样,每一个 Looper 会对应一个线程。因此要在子线程中调用 Java 的方法,需要得到当前线程的 JNIEnv 实例。那么如何在获取当前线程的...原创 2019-01-01 17:19:27 · 2069 阅读 · 0 评论 -
Android 在JNI主线程调用Java方法
1. C++ 全局调用Java方法1.1 C++主线程调用Java方法在 Android C++多线程-创建子线程中演示了在 Java 层调用 native 层的方法,但是如何在 native 层去调用 Java 层的方法呢?下面这个类,我们想在调用 callJavaMethodOnCPPMainThread 方法之后,然后在 native 层回调 JniThreadDemo 的 onSuc...原创 2019-01-01 16:58:05 · 777 阅读 · 0 评论 -
Android 引入 FFMpeg 并打印编解码库
在编译完 Android 平台下的 FFMpeg 库之后,我们接下来接入到 AndroidStudio 工程中。我们验证的目的是想在 AndroidStudio 控制台中打印 FFMpeg 所有支持的编解码库信息,下面我们来一步一步的实现这个过程。要完成这个功能主要有以下 2 步:创建支持 C++ 的 AndroidStudio 工程。配置 FFMpeg1.1 创建支持 C++...原创 2019-01-01 16:18:03 · 23757 阅读 · 5 评论 -
Android C++多线程-创建子线程
在编译完 Android 平台下的 FFMpeg 库之后,我们接下来接入到 AndroidStudio 工程中。我们验证的目的是想在 AndroidStudio 控制台中打印 FFMpeg 所有支持的编解码库信息,下面我们来一步一步的实现这个过程。要完成这个功能主要有以下 4 步:创建支持 C++ 的 AndroidStudio 工程。配置 FFMpeg1.1 创建支持 C++...原创 2018-12-31 23:48:23 · 1177 阅读 · 0 评论 -
Android C++生产者与消费者简易Demo
1. C++生产者与消费者在了解生产者与消费者之前,我们先来看看 C++ 关于线程的一些基本知识:线程锁pthread_mutex_t :用于创建线程锁对象如:pthread_mutex_t mutex;pthread_mutex_init :用于初始化pthread_mutex_t锁对象如:pthread_mutex_init(&a原创 2019-01-04 13:07:55 · 304 阅读 · 0 评论 -
Android国际化入门
国际化 支持不同语言,在不同的国家都可以使用。本文将会介绍如下节点:实现 string 资源的国际化简繁体切换实现在现有业务上,做国际化遇到的一些问题string 资源的国际化实现 在 Android 开发规范中,我们一般不建议在代码或者布局文件中 hard code 我们 string 字符串,而是需要将这些字符串放在单独的 string.xml 文件。...原创 2018-05-10 00:04:50 · 476 阅读 · 0 评论 -
APT动态生成代码的实际应用场景
APT Annotation Processing Tool 注解处理器。 APT 在编译时期就会扫描标识有某一些注解的源代码,并对这些源代码和注解做一些额外的操作,例如获取注解的属性信息,获取标识该注解的源代码类或类成员的一些信息等操作。作用时期 编译阶段我们可以利用编译时期,通过 APT 扫描到这些注解和源代码并生成一些额外的源文件。应用场景 我...原创 2018-05-10 00:04:09 · 1148 阅读 · 2 评论 -
从源码角度分析 Gradle 插件对 Android 的扩展
一、利用 AS 查阅插件源码本文参考的Android Gradle Plugin 的源码是 compile ‘com.android.tools.build:gradle:2.3.0’ Gradle 版本为 gradle-4.41.1、导入源码1、新建一个AS项目2、将 app/build.gradle 的内容修改为:apply plugin: 'java'depend...原创 2019-02-19 00:43:00 · 1052 阅读 · 3 评论 -
ButterKnife 是如何通过 Gradle Plugin 来生成 R2 类的原理分析
一、学习目标本节的学习目标是分析 butterknife 利用 Gradle Plugin 生成 R2.java 文件的过程。新建工程,引入 butterknife ,并在 library 中使用 butterknife。分析为何需要生成 R2.java 文件。R2.java 文件的生成。分析 R.java 和 R2.java 的区别。library 工程出现资...原创 2019-02-21 13:06:12 · 1777 阅读 · 0 评论 -
Gradle-wrapper 的学习笔记
前言Gradle Wrapper 这个东西其实困扰了我很久,对这个东西一直没搞懂,只知道使用 gradlew 这个命令就可以实现 gradle 的功能,但是实际为什么要这样去操作呢?我还是一知半解的,今天花了点时间大概弄明白了为什么会有 Gradle Wrapper 的存在。我们去百度搜索 gradle wrapper 相关博客时,一般都是这样说, gradle wrapper 可以在用户没有...原创 2019-08-24 16:35:36 · 1011 阅读 · 0 评论 -
Android 虚拟机—Dalvik&ART
Dalvik 虚拟机与ART 虚拟机Dalvik是什么?Dalvik 是实现了 JVM 规范的虚拟机,内部默认使用的 CMS 垃圾回收器。但是与 JVM 不一样的是 JMM 运行的 .class 字节码,而 Dalvik 运行的 dex 文件。dex 全称 Dalvik Executable Format ,是一种专门为 Dalvik 设计的一种压缩格式,dex 是由很多 class 压缩后...原创 2019-04-21 15:50:14 · 311 阅读 · 0 评论 -
Java 泛型机制
为什么需要泛型?先来看一段代码,这段代码是用来计算两个数之和,可以看到每次新增一种数据类型,那么就要新增一个方法,这显然是不好的解决方法。public class NoGeneric { public int addInt(int a, int b) { return a + b; } public double addDouble(dou...原创 2019-04-01 19:09:15 · 1068 阅读 · 0 评论 -
「性能优化1.3」延迟加载方案
一、延时加载1.1、为什么要延迟加载?我们在 MainActivity 中优先应该展示视图给用户,而一些其它的数据可以将其延迟再去初始化,例j如我们一般会在进入 MainActivity 时去检测一下当前是否是新用户来确定是否要显示引导图,或者读取当前未读的消息等,这些操作要求的及时性并不是那么高,这样就不会影响视图的展示。1.2、延迟加载的方案是什么?常规实现在 MainActiv...原创 2019-03-19 09:09:36 · 299 阅读 · 0 评论 -
「性能优化1.2」异步优化
一、异步优化在上一小节中,我通过获取应用的启动时间和每一个方法执行之间之后,我们发现,如果在 Application 或者 MainActivity 生命周期中串行去执行这些第三方库的初始化,是会拖慢整个应用的启动过程的,因此我们想通过子线程与主线程并行的方式来分担主线程的工作,从而减少主线程的执行时间。1.1、让任务执行在子线程中1.1.1、常规方案我们常规的方式是怎样的呢?publ...原创 2019-03-18 15:42:33 · 298 阅读 · 0 评论 -
「性能优化2.3」Choreographer检测丢帧
「性能优化1.0」启动分类及启动时间的测量「性能优化1.1」计算方法的执行时间「性能优化1.2」异步优化「性能优化1.3」延迟加载方案「性能优化2.0」布局加载原理「性能优化2.1」LayoutInflater Hook控件加载耗时「性能优化2.2」获取布局的加载时间「性能优化2.3」Choreographer检测丢帧一、Choreographer检测丢帧1.1、基本知识在「性...原创 2019-03-21 19:52:57 · 1458 阅读 · 0 评论 -
「性能优化1.1」计算方法的执行时间
一、计算方法的执行时间我们在前面的几篇博客中分析了如何获取应用的启动时间,我们也知道启动过程中我们能优化的方向就是 Application 和 Activity 的生命周期,那么我们现在就来计算在启动过程 Application 中每一个调用每一个方法的执行耗时。1.1、常规方案手动埋点的方式,这种方案就是跟我们埋点获取应用启动时间是一样的原理,只要在方法执行前和执行后埋点,然后计算这两个...原创 2019-03-17 23:19:21 · 527 阅读 · 0 评论 -
「性能优化1.0」启动分类及启动时间的测量
一、为什么要做启动优化?应用的第一次启动是用户的第一体验,如果启动时间过长,那么就会造成用户的流失。在互联网中有一个8s法则,百科的解释式这样的:8秒原则是互联网的一个著名的原则,用户在访问Web网页时,如果时间超过8秒就会感到不耐烦,如果下载需要太长时间,他们就会放弃访问。所以说优化 APP 的启动速度是很有必要的。二、 启动分类谷歌官方针对以下三种启动方式做了详细的介绍,具体可以参...原创 2019-03-17 23:18:50 · 433 阅读 · 0 评论 -
「性能优化2.2」获取布局的加载时间
「性能优化1.0」启动分类及启动时间的测量「性能优化1.1」计算方法的执行时间「性能优化1.2」异步优化「性能优化1.3」延迟加载方案「性能优化2.0」布局加载原理「性能优化2.1」LayoutInflater Hook控件加载耗时「性能优化2.2」获取布局的加载时间一、获取每一个界面加载耗时在 Activity onCreate 中我们会通过 setContentView 来加载...原创 2019-03-20 22:07:43 · 881 阅读 · 1 评论 -
「性能优化2.1」LayoutInflater Hook控件加载耗时
「性能优化1.0」启动分类及启动时间的测量「性能优化1.1」计算方法的执行时间「性能优化1.2」异步优化「性能优化1.3」延迟加载方案「性能优化2.0」布局加载原理「性能优化2.1」LayoutInflater Hook控件加载耗时一、绘制原理CPU 负责计算需要展示的数据,而 GPU 负责将数据绘制到屏幕上。屏幕绘制过程中涉及到两个基本概念:屏幕刷新率:屏幕刷新率代表屏幕...原创 2019-03-20 22:07:11 · 815 阅读 · 0 评论 -
「性能优化2.0」布局加载原理
「性能优化0」启动分类及启动时间的测量「性能优化1」计算方法的执行时间「性能优化2」异步优化「性能优化4」布局加载原理一、布局加载原理这一小节我们从源码的角度来分析 View 是如何加载的。我简单的绘了一张流程图,根据这张图配合接下来的源码开始我们的工作吧:废话不多说,直接从 setContentView 作为切入点,分析 Activity 的布局加载原理。1.1、Activ...原创 2019-03-20 11:48:49 · 204 阅读 · 0 评论 -
Android音频开发之音频采集
音频采集在 Android 系统中,一般使用 AudioRecord 或者 MediaRecord 来采集音频。AudioRecord 是一个比较偏底层的API,它可以获取到一帧帧 PCM 数据,之后可以对这些数据进行处理。 而 MediaRecorder 是基于 AudioRecorder 的 API(最终还是会创建AudioRecord用来与AudioFlinger进行交互) ,它...原创 2018-05-10 00:03:16 · 3172 阅读 · 0 评论 -
Android音频开发之音频基本概念
Android音频开发 音频采集一般使用 AudioRecod或者 MediaRecord音频采集的来源是什么?MediaRecorder.AudioSource.MIC 一般是麦克风采样率(单位:赫兹) 每秒钟音频采样点个数(8000/44100Hz),模拟信号数字化的过程,用0101来表示的数字信号声道AudioFormat.CHANNEL...原创 2018-05-10 00:02:18 · 565 阅读 · 0 评论 -
android_TabLayout设置setupWithViewPager需要注意的问题
最近项目中使用了android design包中得TabLayout+ViewPager,和大家分享一下我发现了一个的问题。当通过TabLayout.newTab之后,然后通过setupWithViewPager将TabLayout和ViewPager建立关联,这时会发现之前设置的tab消失了,具体的代码和如何查找源码解决见如何代码:示例代码mTl = (TabLayout) findViewBy原创 2016-11-29 22:17:17 · 2869 阅读 · 0 评论 -
android_ThreadLocal
源码中解释到 ThreadLocal 就用于存储数据,每一个线程都会一个数据的拷贝,每一个线程获取到值都是不一样的,并且当前线程修改之后,不会应到其他线程。原创 2016-10-14 11:09:56 · 371 阅读 · 0 评论 -
adnroid_Handler消息发送处理机制
Handler1. Handler 是什么?Handler 是 android 中消息处理机制。一个Handler 会对应一个 Thread 和 该 Thread 绑定的 MessageQueue,Handler 会将 Message 或者 Runnable 发送到 MessageQueue 中,通过 Looper 轮训器的方式从消息队列中轮训消息,每次轮训到的消息都交由 Handler 去处原创 2016-10-14 10:55:52 · 679 阅读 · 0 评论 -
android_View.post(Runnable)在onCreate获取控件宽高分析
在实际开发过程中,我们有时候需要在 activity 中去获取某一个 view 的高度,然后根据该获取的高度去设置其他 view 的高度来达到我们的目的,往往我们都会在 activity#onCreate 直接去 调用 view#getHeight() 但是这个会管用吗,能真正获取到高度吗?这些我们运行下面的实例,然后结合源码的角度去分析这个结果。原创 2016-10-12 17:02:01 · 2825 阅读 · 0 评论 -
android_AsyncTask的源码解析
AsyncTask 下面是AsyncTask的相关结论,相关结论都会在下面的源码分析中一一印证。onPreExecute()是在异步任务执行之前调用的,它是在主线程中运行。doInBackground()是在子线程中运行,该方法执行的耗时的异步任务。onPostExecute(Result result)是执行完doInBackground之后被调用,参数result就是doInB原创 2016-09-26 22:25:47 · 385 阅读 · 0 评论 -
android_自定义多击事件
自定义双击事件点击事件:在控件上按下,离开,有瞬间的停留。双击事件:在单位时间内,双击。多击事件:在单位时间内,多击(双击,三击,四击等)。双击事件代码实例private long firstTimeClick;findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override p原创 2016-08-18 15:06:46 · 405 阅读 · 0 评论 -
android_自定义控件第一炮
自定义控件常见的几种方式:Android View类是所有view的超类。 * 自定义类直接继承View或者ViewGroup。 * 这种方式需要自己去处理AT_MOST的情况。 * 自定义类继承已有的View,例如Button。 * 系统已经帮你处理好AT_MOST的情况,开发人员直接在其基础上去添加新功能即可。 * 自定义组合控件。 * 将需要的布局转化为一个原创 2016-08-18 14:31:31 · 525 阅读 · 0 评论 -
android_如何巧妙在Listview滑动时将头部固定
ListView增加头部,并且该头部在随着ListView滑动时需要固定,下拉刷新采用的是android5的SwipeRefresh。实现方案:在顶部增加一个跟ListView头部一模一样在ListView的onScroll中,判断firstVisibleItem>=0时,就将固定在顶部的布局mLayoutMsgOperate显示出来。(mLayoutMsgOperate显示的时机原创 2016-08-17 10:58:42 · 6521 阅读 · 0 评论 -
android_自定义折叠View
效果如下:原创 2016-04-21 15:16:40 · 1401 阅读 · 0 评论 -
android_关于Activity生命周期设计交互的几个问题
以下是FirstActivity启动SecondActivity的logFirstActivity SecondActivityonCreatonStartonResumeonPauseonCreatonStartonResumeonStop在看了其他博客之后总结的两个问题:问题1:为什么在FirstActivity启动另一个SecondActiv原创 2016-04-21 14:06:34 · 356 阅读 · 0 评论 -
android_ListView条目点击没有效果的解决方案
ListView条目点击没有效果的解决方案分析无法相应的原因首先明白为什么点击没有相应?点击我们就联想到点击事件,一个点击事件能响应在于ACTION_UP事件会被响应,如此说来item点击没有相应我猜测就是ACTION_UP没有被相应到,于是我们去翻翻ListView源码看看:ListView相应Action_up事件的源码private void onTouchUp(MotionEvent ev原创 2016-04-26 18:07:05 · 3010 阅读 · 0 评论 -
android_消息处理机制之Message是如何重复利用的?
问题的引出 我们知道Android开发中我们是一般不会在子线程中去更新UI,而是利用Handler将当前子线程的消息post(Runnable)到主线程中去,这样就可以安全的更新UI了,看过Handler源码的同学应该知道post(Runnable )底层就是将Runnable转化为Message然后交给Handler去处理的。这时我们发现一个问题,那就是在android中大量的UI更新是不原创 2016-11-29 23:25:29 · 1756 阅读 · 0 评论