自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

start_mao的博客

Write everywhere, nowhere to run

  • 博客(76)
  • 收藏
  • 关注

原创 Handler机制——同步屏障

一、消息种类关于Handler机制的基本原理不了解可以看这里: Handler机制源码解析。Message分为3中:普通消息、屏障消息和异步消息。我们通常使用的都是普通消息,而屏障消息就是在消息队列中插入一个屏障,在屏障之后的所有普通消息都会被挡着,不能被处理。不过异步消息却例外,屏障不会挡住异步消息,因此可以这样认为:屏障消息就是为了确保异步消息的优先级,设置了屏障后,只能处理其后的异步消息...

2019-08-10 10:10:19 9557 4

原创 Git头指针分离状态

一、什么是分离头指针状态?我们知道在Git中分支是指向提交,而HEAD指针指向分支。所谓的分离头指针状态就是HEAD不再指向分支,而是直接指向某个commit。二、理解对于下图,此时分支master分支指向c1(c1是某次提交的commit id),HEAD指向master。进行任意一次提交,master分支会重新指向新的提交。如果执行 git checkout commitId就会...

2019-07-05 14:01:51 22692 9

原创 抽象工厂模式

定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。抽象工厂是创建型设计模式,它强调了一系列相关产品对象(属于同一个产品族)的创建过程,它和工厂方法模式的侧重点不同,工厂方法模式更加侧重于同一产品等级,而抽象工厂模式侧重的是同一产品族。简单说就是一个工厂中生产的一系列对象都是同一个产品族的。还是用冰箱来举例,美的生产的产品有美的冰箱、美的空调、美的电风扇。首先创建三个接口://空...

2019-01-06 20:10:48 12722 8

原创 Android AOSP源码编译——AOSP整编(二)

切换到源码目录下执行下面命令。

2023-08-14 20:28:18 770

原创 Android AOSP源码编译——AOSP下载(一)

可以按照文档编辑 ~/bin/repo,把 REPO_URL 一行替换成下面的:REPO_URL = ‘https://gerrit-googlesource.proxy.ustclug.org/git-repo’参考中科大AOSP镜像使用文档:https://mirrors.ustc.edu.cn/help/aosp.html。的时候失败了可以直接通过浏览器下载,复制到bin/下面也是那一样的。到这里我们的源码就下载完成了,接下来就是对源码进行编译了。然后再次执行初始化仓库命令,需要y的直接y就好。

2023-08-10 14:41:30 1592

原创 EventBus源码分析

差不多两年没写博客了,最近想着要找工作了,打算复习下一些常用的开源库,也是这篇博客的由来~再贴一张官网的图。

2023-06-30 23:28:39 191

原创 HashMap源码分析

1.8之前的HashMap存储数据使用了数组+链表方式1.8之后的HashMap存储数据使用了数组+链表+红黑树的方式声明:本文基于jdk1.8分析首先来看其构造函数:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16static final float DEFAULT_LOAD_FACTOR = 0.75f;public HashMap() { this.loadFactor = DEFAULT_

2022-04-06 22:07:25 458

原创 Git tag 操作

通过tag我们可以更好的管理项目的版本历史,tag与branch最大的区别在于,tag 像一个标记 是静态的,对应某次commit。而branch是动态的,之后我们还可以在这个branch上进行commit。标签的基本操作1、 创建标签git tag tag名称git tag v1.0上面的命令会基于当前HEAD 指向的commit id 创建一个名称为v1.0的tag。如果我们想基于某个具体的commit id 创建tag 可以这样:git tag tag名称 commitId

2022-03-23 15:41:30 787

原创 Android 方法耗时打印插件

最近在做启动优化,我需要打印出所有耗时的方法,或者是打印出所有耗时超过指定时间的方法,为此我写了这个工具,主要用到的技术有自定义gradle插件和AMS字节码插桩。具体效果如下, 插桩前: private void c() { try { Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } }插桩

2022-03-10 21:39:12 3337

原创 OpenGL ES 绘制三角形(二)

在上一篇博客我们简单的搭建了一个opengl es的框架,本节让我们看看如何编写OpenGL ES 代码绘制一个简单的三角形吧。首先 我们编写顶点着色器和片元着色器顶点着色器(Vertex Shader) 用来确定形状。片元着色器(Fragment Shader)用来确定颜色着色器代码,如下: //顶点着色器 public static final String VERTEX_SHADER_SOURCE ="" + "attribute vec4 vPos

2022-02-17 15:40:34 2376

原创 搭建OpenGL ES环境(一)

一、搭建OpenGL ES环境1、在AndroidManifest.xml中申明OpenGL ES版本<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mao.openglesdemo"> <uses-feature android:glEsVersion="0x000

2022-02-11 16:40:38 1948

原创 FFmpeg音视频同步

音视频同步本质就是一个你追我赶的过程 快的等一等慢的。慢的走快点去赶上快的。目前常见的同步方式有下面3种:1、以一个外部时间为基准,将音频与视频同步至此时间2、以视频为基准,音频去同步视频的时间3、以音频为基准,视频去同步音频的时间以一个外部时间为基准,将音频与视频同步至此时间,因为人对声音是高度敏感的,所以通常都是以视频去同步音频。本文的实现也是以视频去同步音频的时间。具体来说就是当视频落后于音频,通过丢帧等方式来快速追赶上音频,当视频快于音频,通过休眠等一等音频。相关知识原理:

2021-10-16 23:21:39 1803

原创 CMakeLists学习记录

#最低支持版本cmake_minimum_required(VERSION 3.10.2)#当前工程的名称project("myapplication")#通过file定义变量SOURCE,使用GLOB命令来从源码树中收集源文件列表,这里收集所有的cpp文件#然后将收集到的文件赋给SOURCE变量file(GLOB SOURCE *.cpp)#添加库,构建的时候最终会根据配置生成相应的库add_library( test-lib #指定了库的名称 SH

2021-09-16 23:42:43 103

原创 Netty源码分析——服务启动 (二)

本篇是Netty源码学习的第二篇,从源码角度分析服务启动,主要分析服务端的ServerBootstrap,对于客户端的启动来说,大同小异,并且更简单,就不再重复了。下面代码是ServerBootstrap使用的部分代码 // Configure the server. EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGro.

2021-08-17 21:18:29 190

原创 Netty源码分析NioEventLoopGroup和NioEventLoop ——(一)

机缘巧合之下看了Netty的源码,但是这玩意对我来说使用的频率确实不多,为了加深自己的记忆,也为了以后可以更快的上手,打算写几篇博客从源码角度来梳理下netty的主线, 本篇也是第一篇。在Netty中它的“线程池”和“线程”分别用NioEventLoopGroup和NioEventLoop来表示,通常我们用下面几行代码来配置服务端和客户端的线程池。 //client Bootstrap bootstrap = new Bootstrap(); NioEventLoopGroup grou.

2021-08-16 23:47:57 234

原创 InputManagerService 输入事件是如何分发到view(四)

在第二篇文章介绍了事件通过 connection->inputPublisher.publishMotionEvent 就可以发送到我们app的窗口,那么具体是如何分发的呢?以activity为例,我们打开一个activity就会创建一个PhoneWindow,setContentView会调用PhoneWindow的setContentView,PhoneWindow持有DecorView,DecorView是整个页面的根容器,我们传入的页面会被添加到其中的id为content的子容器中。可以参考

2021-03-27 23:52:04 266

原创 InputManagerService之ANR产生原因(三)

第一篇文章已经分析过,输入事件的分发最终会走到InputDispatcher的dispatchOnce方法。InputDispatcher#void InputDispatcher::dispatchOnce() { nsecs_t nextWakeupTime = LONG_LONG_MAX; { dispatchOnceInnerLocked(&nextWakeupTime); } // release lock}接着进入dispatchOnc

2021-03-23 23:39:21 444 1

原创 InputManagerService之事件分发(二)

通过第一篇文章的学习分析,知道触摸事件最终会走到InputDispatcher的notifyMotion方法。InputDispatcher.cpp#void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { // Just enqueue a new motion event. //将事件进一步封装 MotionEntry* newEntry = new MotionEntry(args->even

2021-03-22 23:06:32 188

原创 InputManagerService的启动过程(一)

从 SystemServer 的main方法开始==》SystemServer#public static void main(String[] args) { new SystemServer().run(); }private void run() { //引导服务:ActivityManagerService、PowerManagerService、PackageManagerService等服务 startBootstrapServices(); /

2021-03-21 18:24:13 477 1

原创 Linux信号机制

一、常见的信号有哪些使用kill -l 命令可以查看所有的信号。常用的命令及说明如下:信号(信号值)信号产生默认动作SIGINT(2)键盘中断Ctrl+c终止进程SIGKILL(9)kill - 9 pid杀死进程&不能被捕获&不能被忽略SIGSEGV(11)段错误、无效的内存引用终止进程SIGTERM(15)kill pid 或 killall 进程名终止进程SIGCHLD(17)子进程死的时候会给父进程发送这个信

2021-03-20 22:18:01 137

原创 Linux进程间通信---管道

管道是Linux进程间通讯的一种手段,管道本质其实就是一个文件。管道的类型有两种:无名管道:用于父子进程的通信,或者兄弟进程之间的通信。有名管道:用户两个独立的进程间通信,有名管道也叫 FIFO。1、无名管道通过man 2 pipe 可以查看Linux手册中关于pipe介绍:#include <unistd.h>int pipe(int pipefd[2]);通过 pipe(int pipefd[2]) 函数可以创建一个无名管道,无名管道是一种半双工(单向)的进程间通信方式。

2020-12-26 16:17:13 150

原创 fork子进程

一、相关函数fork函数:创建一个新的进程,当前进程是新进程的父进程通过man 2 fork命令可以查看linux手册中第二节关于fork函数的介绍 #include <unistd.h> pid_t fork(void);fork函数返回值类型是pid_t ,本质就是一个int类型的值,它有3中可能的返回结果:-1:创建失败,在父进程中返回-10:创建成功,当前进程是子进程其他:创建成功,在父进程中返回子进程的pid(进程 ID)linux系统还提供了一些函数,用来获

2020-12-22 22:26:01 3743

原创 Linux物理内存与虚拟内存

一、为什么需要虚拟内存要理解虚拟内存首先要明白为什么需要虚拟内存,物理内存就是我们通常所说的内存条。我们知道,相比于从硬盘中读写数据,直接读写内存的速度要快很多,但是内存的大小要比硬盘小很多。 要知道每个进程都有自己独立的4G内存空间,以16G的内存来说,如果我们在加载程序的时候直接给它分配4G大小的内存,那么像这种大小的程序,只要加载4个我们的内存就会被全部耗尽。然而,我们查看进程管理器可以发现系统中可能运行着几十个程序。为了解决这个问题,就有了虚拟内存的概念,它是利用磁盘空间虚拟出一块逻辑内存,用作虚

2020-12-17 23:41:02 745

原创 GCC编译的4个阶段

GCC编译一共有4个阶段:预处理、编译、汇编、链接。gcc指令的一般格式gcc [选项] 要编译的文件 [选项] [输出文件]选项说明-E预处理源文件-S编译为汇编代码-c编译为目标文件-o outfile指定输出文件的文件名eg:下面是一段很简单的hello.c代码,以这段代码为例。#include <stdio.h>#define NAME "mao"void main(){ printf("hello:%s\n",NAME

2020-12-12 21:48:39 5129

原创 Linux常用命令

1、文件操作cd dirName 进入某个目录cd / 进入到根目录cd … 回退到上一级目录ls 可以查看当前文件夹下面的所有文件ls -a 列出目录所有文件,包含以.开始的隐藏文件ls -l 除了文件名之外,还将文件的权限、所有者、所属组、文件大小等信息详细列出来eg: 执行ls -l结果如下:以红色圈出来的文件信息为例:第一列:第一个字母代表了文件的类型,有如下文件类型:文件类型-普通文件,包括纯文本文件、二进制文件、各种压缩文件等d目录

2020-12-09 23:18:01 2596

原创 Git命令基本使用

一、基本操作1、 首次拉取远程仓库代码git clone 远程仓库地址 [本地文件夹名称]本地文件夹名称是可选的,如果不指定拉取到本地后,默认名称为远程仓库名字。2、 更新代码远程代码有变更,你想把本地代码更新时,可以通过 git pull 命令更新git pull3、git status:命令用于显示工作区和暂存区的状态。通常有下面几种状态:Untracked: 未跟踪,一般为新增文件,还没有加入到 git 库,不参与版本控制。通过 git add 状态变为 Staged.Chan

2020-12-01 23:23:14 749 1

原创 数据结构--顺序表与ArratList

本片文章主要学习顺序表的核心思想,关于ArrayList不会分析每个方法的实现,也没必要,把握思想即可。

2020-10-24 15:05:36 221

原创 OpenSLES播放PCM音频数据

如何在项目中引入OpenSL ES在android ndk相关目录下已经引入了opensles.so。因此可以在 CMakeList.txt中加入 直接使用。cmake_minimum_required(VERSION 3.4.1)add_library( native-lib SHARED native-lib.cpp)target_link_libraries( android native-lib

2020-09-20 11:55:21 810 1

原创 ActivityManagerService(AMS)启动流程

Android是基于Linux系统的,Linux启动后用户空间创建的第一个进程是init进程,而Zygote进程是init进程创建的,Zygote进程主要干两件事。1、孵化应用进程,我们app所在进程都是他fork出来的。2、创建SystemServer进程,我们常见的AMS、PMS、WMS等都是SystemServer进程中的服务。而在SystemServer中会启动许多的服务,包括ActivityManagerService、PackageManagerService等服务、PowerMana

2020-07-05 21:48:59 307

原创 Android 类加载机制源码分析

ClassLoader介绍任何一个 Java 程序都是由一个或多个 class 文件组成,在程序运行时,需要将 class 文件加载到 JVM 中才可以使用,负责加载这些 class 文件的就是 Java 的类加载机制。ClassLoader 的作用简单来说就是加载 class 文件,提供给程序运行时使用。每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个 ClassLoader 加载的。public final class Class<T>{ //

2020-06-17 23:07:01 492

原创 深入理解Java序列化

一、概念序列化:把Java对象转化为二进制字节码的过程。反序列化:将在序列化过程中所生成的二进制字节码转换成Java对象的过程。为什么需要序列化呢?主要有两个作用:持久化,通过序列化把Java对象转化为二进制字节码,然后可以将其保存在文件中,在合适的时候再反序列化恢复为一个对象。传输,网络上传输的数据都是二进制的形式,再网络上传输一个Java对象需要先序列化为二进制数据,然后在网络的另一端通过反序列化将接收到的二进制数据转为Java对象。二、Serializable接口public in

2020-05-31 19:01:38 582

原创 MediaPlayer源码分析(一)

对于创建MediaPlay我们可以使用create方式,也可以通过new MediaPlay的方式。下面以create方式来切入源码。public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder, AudioAttributes audioAttributes, int audioS...

2020-03-16 22:38:56 722

原创 Linux下编译FFmpeg库

一、下载NKD下载地址。找到ndk-r17复制下载链接接着打开linux终端,用wget命令下载链接资源,然后回车等待资源下载完成。二、ndk环境配置首先解压ndk的zip文件。执行unzip android-ndk-r17c-linux-x86_64.zip?hl=zh_cn 解压该文件(可以使用ls命令查看文件的名称)。解压完成可以看到多了一个解压后的文件配置ndk的环境...

2020-03-01 16:52:36 1557 1

原创 一行代码实现任意View的粒子爆炸效果

使用方法很简单,只需要一行代码。BombViewUtil.bomb(view,null);//该view需要展现粒子爆炸效果时调用比如对于常见的ImageView、Button、TextView调用上面的方法,效果如下。分析实现:1、首先要明白爆炸的不是真正的TextView或者Button,而是他们对应的快照。通过下面这个方法就可以获得某个View对应的Bitmap。 targe...

2019-12-12 22:49:16 392

原创 Activity显示原理

Activity是通过它的setContentView方法来显示我们传入的布局的。 Activity#setContentView public void setContentView(@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); //... }在se...

2019-12-07 16:20:58 364

原创 状态模式

文章目录定义目的状态模式的角色举例状态模式优缺点使用场景定义状态模式(State Pattern) :一个对象在其内部状态改变时改变它的行为,这个对象看起来像是改变了其类。状态模式是一种对象行为型模式。目的当一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的对象,对象在不同状态下有着不同的行为,此时可以使用状态模式。状态模式主要解决的是当控制一个对象状...

2019-11-16 16:38:25 254

原创 OpenCV安装配置(Windows下)

一、OpenCV简介OpenCV(Open Source Computer Vision Library)开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法,OpenCV 使用 C/C++ 开发,同时也提供了 Python、Java、MATLAB 等其他语言的接口。可以运行在Linux、Windows、Android和Mac OS等操作系统上。OpenCV 的应用领域...

2019-10-31 19:05:04 676

原创 JNI学习笔记——JNI基础知识(二)

一、静态局部缓存在下面的代码中多次调用了native层的set方法。public class HelloJNI { //加载动态库 static { System.load("D:\\programme\\c++\\repos\\JNIHello\\x64\\Debug\\JNIHello.dll"); } public static int ...

2019-10-25 21:04:32 375

原创 JNI学习笔记——JNI开发流程(一)

1、什么是JNI?Java本地接口(Java Native Interface ),JNI是属于Java特有的特性,主要作用是让Java代码与用其他编程语言(例如C、C ++、汇编)编写的应用程序和库进行交互。通过JNI,可以让Java具备跨平台的特性,增强Java和本地语言交互的能力。2、什么时候需要用到JNI?因为JAVA是跨平台的,一些与平台相关的功能就不能很好的支持,这时可以使用J...

2019-10-24 21:56:59 211

原创 深入理解LayoutInflater

LayoutInflater在我们的日常开发中非常常见,通过它可以将我们的布局文件加载成一个View实例,那么LayoutInflater是如何将一个布局文件加载成View实例的呢?一、LayoutInflater的获取LayoutInflater的获取有三种方式:LayoutInflater.from(context)。context.getSystemService(Context....

2019-09-12 18:29:56 628

空空如也

空空如也

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

TA关注的人

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