自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

六号表哥

你应该了解真相,真相会使你自由。

  • 博客(89)
  • 资源 (1)
  • 收藏
  • 关注

原创 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 2772 3

原创 Gradle-wrapper 的学习笔记

前言Gradle Wrapper 这个东西其实困扰了我很久,对这个东西一直没搞懂,只知道使用 gradlew 这个命令就可以实现 gradle 的功能,但是实际为什么要这样去操作呢?我还是一知半解的,今天花了点时间大概弄明白了为什么会有 Gradle Wrapper 的存在。我们去百度搜索 gradle wrapper 相关博客时,一般都是这样说, gradle wrapper 可以在用户没有...

2019-08-24 16:35:36 837

原创 Java 数据结构—阻塞队列学习笔记

文章目录特点阻塞你是怎么理解的呢?简单理解如下如何实现阻塞的呢?阻塞队列主要有三种实现类BlockingQueue 基础 APISynchrousBlockingQueueArrayBlokingQueue阻塞队列在线程池的应用execute 函数的工作原理入队出队项目地址特点阻塞队列 BlockingQueue 是线程安全,所有的操作都加了锁。阻塞你是怎么理解的呢?队列主要的操作不外乎就...

2019-08-18 00:52:25 282

原创 序列化机制——Serializable工作原理

序列化与反序列化的概念从广义上讲,数据序列化就是将数据结构或者是对象转换成我们可以存储或者传输的数据格式的一个过程,在序列化的过程中,数据结构或者对象将其状态信息写入到临时或者持久性的存储区中,而在对应的反序列化过程中,则可以说是生成的数据被还原成数据结构或对象的过程。在对象序列化和反序列化角度来看,Java 提供了 Serializable 接口,而 Android 提供特有的 Parcel...

2019-06-02 21:08:15 11357

原创 lancet 库的工作原理

Lancetlancet 是一个轻量级Android AOP框架。dependencies{ classpath 'me.ele:lancet-plugin:1.0.4'}apply plugin: 'me.ele.lancet'dependencies { provided 'me.ele:lancet-base:1.0.4'}下面使用 Lancet 来 ho...

2019-04-24 20:26:11 4695 1

原创 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 226

原创 Java 注解工作原理

文章目录注解的本质定义和使用注解定义注解类应用注解获取被注解的信息验证注解的工作就是通过动态代理实现的。断点验证我们的结论将动态代理类写入到磁盘总结参考注解的本质这里先得出结论,注解的工作就是通过动态代理实现的。定义和使用注解下面来定义一个最简单的注解,并通过这个注解引出注解的本质。下面编写的类并没有实际意义,只是为了演示而已。定义注解类@Retention(Retentio...

2019-04-21 15:47:25 480

原创 「性能优化4.0」运行期间检测不合理的图片

Bitmap 内存模型在 API10 之前,Bitmap 对象本身存在 Dalvik Heap 中,像素是存在 native 中,这样像素并不会占用 Heap 空间,也就不会造成 Heap 内存溢出。但是缺点是Bitmap 对象被回收了,但是 native 层像素回收的时机可能跟 Heap 中 Bitmap 的对象回收时机不对应。API10之后,像素也放在 Dalvik Heap...

2019-04-20 23:44:18 442

原创 「性能优化3.1」Android多线程优化

文章目录多线程优化给线程起名字目的是什么?什么时候设置?检测关键异步任务的耗时情况避免直接创建Thread直接创建Thread的弊端锁定线程的创建者设置线程优先级参考项目地址多线程优化给线程起名字目的是什么?在出 bug 时方便定位到是哪个线程出问题。在 Android SDk 提供的类中,也是有给线程起名字的。IntentService//IntentService.ja...

2019-04-16 19:20:36 206

原创 「性能优化3.0」Android线程调度&异步方式汇总

文章目录线程调度与线程调度模型nice valuecgroup(control group)CPU 密集型与 IO 密集型多线程优化的注意点Android 的异步方式参考线程调度与线程调度模型任意时刻,只有一个线程占用 CPU,处于运行状态。而多线程并发执行就是轮流获取 CPU 执行权。分时调用模型轮流获取 CPU 执行权,均分 CPU 执行时间。抢占式调度模型优先级...

2019-04-16 00:15:46 478

原创 Java 虚拟机内存模型—线程私有

文章目录JVM 内存模型线程私有区域程序计数器虚拟机栈栈帧的组成StackOverflowError本地方法栈逃逸分析优化线程私有部分的回收问题参考JVM 内存模型.java 源文件 -> javac 工具编译 -> .class 文件 -> JVM 解析 -> 010101 机器码 -跑在不同的操作系统上。基于上面的流程可以看出,java 是一个跨平台语言。...

2019-04-15 12:01:32 973

原创 Java 并发编程—volatile 关键字

volatile 关键字volatile 作用volatie 用于修饰变量,它有两个作用。它可以保证变量在多线程之间是可见的,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。禁止指令重排序。volatile 保证变量的可见性先来看一下 volatile 保证变量在线程之间的可见性问题,在下面这段代码中,isContinuePrint共享变量,printThread...

2019-04-14 18:39:39 111

原创 Java 并发编程—线程间的共享和协作(二)

线程间的共享和协作文章目录线程间的共享和协作Lock 显示锁Lock APIReentrantLock什么是可重入锁?ReentrantLock实现公平锁和非公平锁读写锁ReentrantReadWritLockCondition接口对比 Object 的 wait 和 notify使用 Lock 配合 Condition 实现等待通知机制总结参考Lock 显示锁在 Java 中,一般情况...

2019-04-14 03:23:59 342

原创 Java 并发编程—线程间的共享和协作(一)

线程间的共享和协作线程间的共享JVM 会为每一个线程独立分配虚拟机栈空间,本地方法栈空间以及程序计数器,而对于共享内存中的变量,是对每一个线程而言是共享的,因此多线程并发访问共享内存中的变量时就会出现线程安全问题。具体可以参考JVM 内存模型这篇博客。synchronized 内置锁在前面提到共享资源在多个线程并发访问时会出现线程安全问题,而解决线程安全问题就是要解决以下两个问题,一是要...

2019-04-12 15:53:41 429

原创 Java类加载器-动态加载外部dex

Android 类加载Android 只能加载识别 dex 文件,因此需要将 .java 文件编译 .class 文件,然后将 .class 优化为 .dex 文件。过程:.java -> .class -> .dex下面来练习如何去加载一个 dex 文件,并调用 dex 中的方法。获取需要动态加载的 dex 文件编写 DynamicClass.java 类public...

2019-04-10 21:30:26 1149 1

原创 Java 并发编程基础知识

CPU 核心线程数和线程数的关系目前的 CPU 有双核,四核,八核,一般情况下,它和线程数是1:1的对应关系,也就是四核 CPU 一般就能并行执行 4 个线程。但 Intel 引入超线程技术后,使核心数与线程数形成1:2的关系,也就是我们常说的 4核8线程线程调度任意时刻,只有一个线程占用 CPU,处于运行状态。而多线程并发执行就是轮流获取 CPU 执行权。线程调度模型分时调用...

2019-04-07 15:29:01 275

原创 劣实基础–Java 动态代理机制

代理模式代理在我们日常生活中经常出现,例如我们去租房,为了方便我们会去找中介,让他们帮我去找房子,事后我们给他一定比例的中介费就可以了,这种好处就不需要我们自己去奔波租房。在程序中也有代理这种思想,当我们想在一个已有的类的方法被调用前和调用后都输出一段日志信息,而我们目前无法修改类内部的结构,但是我们可以生成一个代理对象,通过代理对象去调用目标对象的这些方法,因为目标方法会被代理对象所调用,...

2019-04-04 00:59:37 798

原创 劣实基础–Java 反射机制

反射与动态代理反射一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。这时候,我们使用 JDK 提供的反射 API 进行反射调用。反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法或者属性。...

2019-04-03 17:39:13 1200 1

原创 Java 泛型机制

为什么需要泛型?先来看一段代码,这段代码是用来计算两个数之和,可以看到每次新增一种数据类型,那么就要新增一个方法,这显然是不好的解决方法。public class NoGeneric { public int addInt(int a, int b) { return a + b; } public double addDouble(dou...

2019-04-01 19:09:15 1031

原创 Java 并发编程—CAS 机制

CAS 机制在介绍 CAS 机制之前,来看下面这段代码:它的执行结果是会是 200 吗?public class NoAtomicPersonCount implements Runnable { private int personCount = 0; public static void main(String[] args) { NoAtomicPer...

2019-03-31 19:35:25 183 1

原创 Java 虚拟机–内存模型

一、JVM 内存模型.java 源文件 -> javac 工具编译 -> .class 文件 -> JVM 解析 -> 010101 机器码 -> 跑在不同的操作系统上。基于上面的流程可以看出,java 是一个跨平台语言。本节来分析 Java 对象如何进行分配和回收。JVM 运行时数据区主要由线程私有区域和线程共享区域组成。线程私有区域:虚拟机栈...

2019-03-28 00:04:11 158

原创 「性能优化2.4」 AsyncLayoutInflater实现异步加载布局

「性能优化1.0」启动分类及启动时间的测量「性能优化1.1」计算方法的执行时间「性能优化1.2」异步优化「性能优化1.3」延迟加载方案「性能优化2.0」布局加载原理「性能优化2.1」LayoutInflater Hook控件加载耗时「性能优化2.2」获取布局的加载时间「性能优化2.3」Choreographer检测丢帧「性能优化2.4」 AsyncLayoutInflater实现异...

2019-03-21 23:22:31 3054

原创 「性能优化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 1346

原创 「性能优化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 769 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 725

原创 「性能优化2.0」布局加载原理

「性能优化0」启动分类及启动时间的测量「性能优化1」计算方法的执行时间「性能优化2」异步优化「性能优化4」布局加载原理一、布局加载原理这一小节我们从源码的角度来分析 View 是如何加载的。我简单的绘了一张流程图,根据这张图配合接下来的源码开始我们的工作吧:废话不多说,直接从 setContentView 作为切入点,分析 Activity 的布局加载原理。1.1、Activ...

2019-03-20 11:48:49 156

原创 「性能优化1.3」延迟加载方案

一、延时加载1.1、为什么要延迟加载?我们在 MainActivity 中优先应该展示视图给用户,而一些其它的数据可以将其延迟再去初始化,例j如我们一般会在进入 MainActivity 时去检测一下当前是否是新用户来确定是否要显示引导图,或者读取当前未读的消息等,这些操作要求的及时性并不是那么高,这样就不会影响视图的展示。1.2、延迟加载的方案是什么?常规实现在 MainActiv...

2019-03-19 09:09:36 247

原创 「性能优化1.2」异步优化

一、异步优化在上一小节中,我通过获取应用的启动时间和每一个方法执行之间之后,我们发现,如果在 Application 或者 MainActivity 生命周期中串行去执行这些第三方库的初始化,是会拖慢整个应用的启动过程的,因此我们想通过子线程与主线程并行的方式来分担主线程的工作,从而减少主线程的执行时间。1.1、让任务执行在子线程中1.1.1、常规方案我们常规的方式是怎样的呢?publ...

2019-03-18 15:42:33 262

原创 「性能优化1.1」计算方法的执行时间

一、计算方法的执行时间我们在前面的几篇博客中分析了如何获取应用的启动时间,我们也知道启动过程中我们能优化的方向就是 Application 和 Activity 的生命周期,那么我们现在就来计算在启动过程 Application 中每一个调用每一个方法的执行耗时。1.1、常规方案手动埋点的方式,这种方案就是跟我们埋点获取应用启动时间是一样的原理,只要在方法执行前和执行后埋点,然后计算这两个...

2019-03-17 23:19:21 462

原创 「性能优化1.0」启动分类及启动时间的测量

一、为什么要做启动优化?应用的第一次启动是用户的第一体验,如果启动时间过长,那么就会造成用户的流失。在互联网中有一个8s法则,百科的解释式这样的:8秒原则是互联网的一个著名的原则,用户在访问Web网页时,如果时间超过8秒就会感到不耐烦,如果下载需要太长时间,他们就会放弃访问。所以说优化 APP 的启动速度是很有必要的。二、 启动分类谷歌官方针对以下三种启动方式做了详细的介绍,具体可以参...

2019-03-17 23:18:50 357

原创 从源码的角度分析 Gradle 是如何生成 BuildConfig 类的

一、学习目标BuildConfig 类是 Gradle 自动生成的,存放在 /build/generated/source/buildConfig/debug(release)/包名/BuildConfig 因此我们需要在 Gradle 构建时来配置这个类的属性。而在开发中,我们想在 BuildConfig 中增加一个 DEBUG_LOG 属性,用来判断是否开启 log 输出日志的开关。下面我...

2019-02-21 22:17:34 1666 1

原创 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 1589

原创 从源码角度分析 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 959 3

原创 SharedPreference 源码分析

一、 本节目标SharedPreference 是一个轻量级的 key-value 存储框架。开发者很容易地可以使用它的 api ,但是如果不恰当的使用可能会导致一些问题,所以针对如何使用和处理这些问题,列出了以下几个小点。1、sp 实例的获取。2、sp 是如何进行读写操作和缓存处理的?3、commit 和 apply 的区别?4、不恰当使用 sp 的一些坑。5、s...

2019-01-31 15:14:01 566

原创 Android 利用 FFmpeg 解码音视频数据

一、本节目标继上节获取解封装的 AvPacket 数据包之后,我们知道 AvPacket 存储的都是编码后的数据,因此我们需要将数据包进行解码,从而得到原始的数据,而 FFmpeg 使用 AvFrame 这个数据结构来存储解码后的数据。对于解码后的数据:视频原始数据一般是用 yuv 表示。音频原始数据一般用 pcm 表示。而在开始之前,我们还是来回顾一下 FFmpeg 处理流的整个过...

2019-01-21 00:11:39 1557

原创 Android 利用 FFmpeg 获取每一帧数据信息

一、本节目标在上一节中演示了如果打开码流并且获取音视频的相关信息。这一节来获取码流每一帧的信息。在开始之前,首先来了解一下 FFmpeg 的对码流的处理过程。FFmeg 处理流程如下:1、得到输入流,打开输入流2、解封装格式->得到编码数据包 AvPacket3、解码数据包->得到解码的原始数据 AvFrame4、处理数据->例如滤镜处理等5、编码原始数据-&...

2019-01-20 20:51:03 2964

原创 Android 利用 FFmpeg 打印码流信息

一、获取码流信息我们希望通过 FFmpeg 获取码流如下一些信息:码流的数量码流的时间长度音视频的索引值视频帧率视频宽高视频像素格式视频的编解码器视频的比特率音频的采样率音频的通道数音频的采样格式音频帧大小音频编解码器二、打开码流avformat_open_input 连接服务器和解析码流头部信息。/* * 参数1:封装格式上下文,要注意这个需要记得释放。...

2019-01-20 19:46:59 639

原创 FFmpeg 命令

一、录制命令1.1、获取支持的设备要录制屏幕,首先要知道当前笔记本支持的输入设备。ffmpeg -devicesDevices: D. = Demuxing supported .E = Muxing supported -- D avfoundation AVFoundation input device D lavfi Libavfilter ...

2019-01-20 18:45:39 1366

原创 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 263

原创 Android 在JNI子线程调用Java方法

1. C++ 全局调用Java方法之前讨论过,如何C++主线程中调用 Java 函数C++主线程调用Java方法,下面来看看如何在子线程中调用 Java 函数。由于JNIEnv是与线程绑定的,就像 Android 的 Looper 也是和线程绑定一样,每一个 Looper 会对应一个线程。因此要在子线程中调用 Java 的方法,需要得到当前线程的 JNIEnv 实例。那么如何在获取当前线程的...

2019-01-01 17:19:27 1838

EventBusDemo源码

EventBusDemo源码

2016-05-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除