
技术分享
qinbin2015
坚持就是胜利
展开
-
零开始玩转SpannableString
想必我们在开发的会遇到图文混排的需求,如下图:注意这里的头像是网络图片,并且头像和昵称、直播间都是可点击跳转的。这种效果的实现其实离不开SpannableString,对于这个类android开发者都不会陌生,使用它很容易实现这个效果!真的吗???一眼看去确实离不开这个类,但是它能够填充网络图片吗? 这是我们需要考虑的问题。那我们先从简单的开始一、本地图片,图文混排1、首先简单实现如下效果:代码如下:SpannableString sb = new SpannableString(" 我是测试原创 2020-08-08 17:06:57 · 739 阅读 · 0 评论 -
android端使用mockServer
小伙伴们可能在开发的过程中遇到这样的痛点:比如一个新的项目开发需求下来了,正常来说,要等到服务端将接口开发完毕,我们才去对接数据。但是,往往后端人员又很忙,不能立马开发出接口,这样就大大降低了移动端的开发进度,所以,为了能够解决这个问题,我们就不得不自己设计接口,模拟服务端数据。等到真正测试的时候,将接口域名替换即可。这样,我们就不得不借助mock-server这款强大的工具了。目前,我接触了两种类似的服务端模拟,开发者可以根据不同的开发需求,用到项目中去。一、nodeJs+express1、安装nod原创 2020-05-29 17:24:38 · 1089 阅读 · 0 评论 -
Mockito代码测试
随着业务模块的增加,app的编译速度就会变慢,如果开发过程中,我们仅仅需要测试一个模块,普遍的做法就是重新编译运行,导致开发效率变低。这样我们就需要构建单元测试代码。普通的测试类,如果相互依赖(比如A类依赖B类,我们需要测试A类,就需要构建B类对象),这样的操作,也会增加测试成本,还不如直接运行。所以就需要借助第三方框架,本文主要介绍Mockito的集成使用。一、集成在项目的build.gra...原创 2020-02-25 15:31:48 · 361 阅读 · 0 评论 -
android 8.0源码分析activity启动流程
当我们点击桌面图标的时候,会通过Launch应用,启动另外一个进程来启动当前应用的activity。那么这个activity的启动流程是怎样的呢?当然这一部分分为两个关键点:application启动activity启动一、application启动二、activity启动...原创 2019-10-28 15:05:06 · 6487 阅读 · 0 评论 -
自定义控件之仿豆瓣笑脸进度加载
最近看到豆瓣的笑脸loading很有意思,看一张效果图:下面分析一下如何实现这样的效果:默认状态是一张笑脸的状态(一个嘴巴,两个眼睛,默认状态)开始旋转,嘴巴追上眼睛(合并状态)追上以后自转一周(自转状态)然后逐渐释放眼睛(分离状态)回到初始笑脸状态(默认状态)一、默认状态首先需要确定好嘴巴和眼睛的初始位置,我这里的初始化嘴巴是一个半圆,在横轴下方。眼睛分别与横轴夹角60度,...原创 2019-08-05 16:51:32 · 437 阅读 · 0 评论 -
final修饰符
final修饰符大家在开发的过程中都有使用过,那么final修饰的字段能够使用反射修改吗?这个问题值得反思。针对这个问题,看如下两种情况:情况一代码如下:main方法执行反射修改num2的值,结果如下:明显这里是被修改成功了。情况二同样在main方法执行反射修改num2的值,结果如下:结果这里没有修改成功。仔细观察发现我只是修改了final修饰字段在声明的时候有没有给定初始...原创 2019-09-06 10:39:11 · 109 阅读 · 0 评论 -
android开发几种常用单例分析
一、饿汉式写法一:写法二:两种写法都是在类加载的时候就加载了实例,没有达到Lazy Loading的效果。优点:1、写法简单2、能够解决线程同步的问题缺点:由于在类加载的时候就申请了一块内存,如果一直没有用到这个实例,就会导致内存的浪费。二、懒汉式写法一:缺点:线程不安全,比如两个线程同时访问这个方法,就会导致创建两次对象,拿到的实例对象不一样,违背了单例的原则。写法...原创 2019-09-03 17:58:45 · 159 阅读 · 0 评论 -
设计模式--责任链模式
什么是责任链模式呢?所谓的责任链模式就是使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。比如现在比较流行的okHttp网络请求框架就是采用了责任链模式。下面将手写一个简易的责任链。一、IChain这是一个接口,所有的子链都需要实现该接口。isConsume:当前链条是否消费chain:责...原创 2019-08-26 17:58:18 · 258 阅读 · 0 评论 -
浅谈android中的线程池
什么是线程池?顾名思义,就是存放线程的池子,也就是说一个线程池中可以存放多个线程。那为什么要设计出来线程池呢?最主要的原因就是线程复用的原因。如果没有线程池,我们每次网络请求都需要new Thread。如果有100个任务同时执行,这样就会导致资源的开销非常大,而对于线程池来说。我们只需要把100个任务加入其中即可,它内部会维护一个队列。一、线程池的类属关系最原始的线程池类是一个接口Execut...原创 2019-08-23 17:41:58 · 207 阅读 · 0 评论 -
linux如何编译ffmpeg,并集成到AS中
教程中,我用的是ubuntu虚拟机。接下来的配置都是在linux环境下进行配置的一、LINUX环境下编译成静态库1、下载FFmpeg,这里我下载的是ffmpeg-4.0.2版本下载地址:ffmpeg-4.0.2 gitub下载地址下载完成以后使用unzip命令解压到当前目录,我这里是放到桌面上了2、下载ndk,记住必须不能高于r17c,因为要和ffmpeg版本进行适配,否则高于...原创 2019-05-29 11:14:34 · 800 阅读 · 1 评论 -
增量更新
一、定义增量更新是指在进行更新操作时,只更新需要改变的地方,不需要更新或者已经更新过的地方则不会重复更新,增量更新与完全更新相对。对于我们app来说,一般对于用户来说用户的流量是很宝贵的,如果我们只改变了app中的一个变量,比如i。那么我们就需要重新发版,供用户下载更新整个app,而增量更新就不需要这样的操作了,虽然最终也是需要用户来安装的,但是用户下载的只是我们更改的部分。并且这个技术已经很...原创 2019-05-28 15:34:14 · 4036 阅读 · 0 评论 -
阿里AndFix与sophix热修复原理解析
一、首先需要了解java的内存管理机制,大致分为3类方法区 堆区 栈区三种内存区域定义如下:方法区:当JVM使用类加载器定位class文件,并将其输入到内存中时,会提取class文件的类型信息,并将这些信息存储到方法区中。同时放入方法区中的还有该类型中的类静态变量。堆内存:java程序在运行时创建的所有类型对象和数组都存储在堆中。JVM会根据new指令在堆中开辟一个确定类型的对象...原创 2019-05-23 17:13:26 · 1640 阅读 · 0 评论 -
RGB、YUV420、NV21、I420编码区别
一、RGB与YUV首先了解视频编码为什么使用YUV420而不是rgb。那么需要了解两者的原理,看图说话所以从内存的角度来说,yuv单位像素使用的内存更低,但是两者表示的效果是一致的,也可以认为rgb过度绘制了,把人眼无法分辨的区域也进行了绘制。下面看一下两者之间内存暂用对比,这里采用·rgb24对比RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255...原创 2019-05-30 11:02:31 · 11262 阅读 · 0 评论 -
自定义控件之水波纹特效
首先看一下效果:实现这个效果,其实需要分析一下有几个动画 。很明显一开始是一个小圆,慢慢的在外扩散,所以这里有两个动画,x轴缩放动画,y轴缩放动画。另外在扩散的过程中,圆的透明度也是在不断变化的,所以有一个透明度的动画。总结起来,有3个动画,如下:x轴动画,对应的属性是ScaleX y轴动画,对象的属性是ScaleY 透明度动画,对应的属性是Alpha(1-->0)下面看代...原创 2019-05-09 20:38:59 · 370 阅读 · 0 评论 -
抽象类与接口的异同点
先上代码,后面对照代码分析 interface MyInterface{ //此处省略了 final 和 修饰符信息 完整的为public final int i=0; //它是一个静态共有的常量 int i=0; //此处省略了abstract修饰符 完整的为abstract void onItem(); /...原创 2019-04-23 09:46:55 · 2398 阅读 · 0 评论 -
设置沉浸式布局适配4.4及以上所有机型
对布局进行沉浸式设置,对于不同手机版本号设置方法是不同的。由于4.4以下手机不占据状态栏,所以只考虑4.4版本以上手机。1、4.4版本手机(1)第一种方式:设置主题样式<item name="android:windowTranslucentStatus">true</item><item name="android:windowTranslucent...原创 2019-04-15 10:00:33 · 383 阅读 · 0 评论 -
记录一下属性动画设计原理
动画按照大类分为属性动画、逐帧动画、补间动画。其中属性动画使用的是比较普遍的,比如平移,缩放、旋转等效果都可以使用属性动画实现。最近有在观看大佬的手撸属性动画视频,把其中的关键点记录下来。我们如何使用属性动画,比如我们想让一个view在3s中实现放大两倍后再回到初始大小,可以这样做 ObjectAnimator objectAnimator = ObjectAnimator. ...原创 2019-04-12 11:16:04 · 440 阅读 · 0 评论 -
UI绘制流程及原理
首先需要了解我们的view是如何被添加到窗口中点击activity中setContentView会进入系统源码中public void setContentView(@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(...原创 2019-03-28 10:41:06 · 400 阅读 · 0 评论 -
直播--如何搭建rtmp推流服务器
首先需要了解什么事rtmp协议概念:与HTTP(超文本传输协议)同样是一个基于TCP的Real Time Messaging Protocol(实时消息传输协议)。由Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的一种开放协议 。在国内被广泛的应用于直播领域。HTTP默认端口为80,RTMP则为1935。本质上我们通过阅读Adobe的协议规范,通过与服务...原创 2019-05-29 14:14:06 · 9024 阅读 · 0 评论 -
H264视频编码原理
一、为什么要对视频编码视频是由一帧帧的图像组成,就像gif图片一样。一般视频为了不会让人感觉到卡顿,一秒钟至少需要16帧画面(一般30帧)。加入该视频是一个1280x720的分辨率,那么不经过编码一秒钟传输的大小为1280x720x60~=843M。所以不经过编码的视频根本没法保存和传输。现在市面上主要将编码分为两大类H.264和MPEG。后面一种主要用于DVD,机顶盒等设备。h264编码是一...原创 2019-06-01 19:57:33 · 4904 阅读 · 0 评论 -
Binder原理之PMS工作原理和代码模拟
1111原创 2019-07-14 14:00:57 · 505 阅读 · 0 评论 -
Binder原理之Apk安装原理
12原创 2019-07-12 17:05:43 · 353 阅读 · 0 评论 -
设计模式--外观模式
外观模式又称门面模式,定义如下:外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。使用:比如我们可以模拟一个场景,图片加载。首先加载一张图片会从内存中读取,内存中读取不到,会从本地磁盘读取,还是没有读取到,只有从网络上重新下载。对于这...原创 2019-06-11 09:49:12 · 113 阅读 · 0 评论 -
设计模式--简单工厂模式
实现简单的工厂模式有两种方式代码传参形式 配置文件形式首先准备好一个实体类Student.java。代码如下:public class Student { private String name; public Student(String name) { this.name = name; } public String getN...原创 2019-06-10 15:23:17 · 148 阅读 · 0 评论 -
视频播放器--音视频同步
之前已经完成了音频和视频的播放,但是发现音频的播放速度要明显快于视频。由于音频和视频解码时间、渲染时间的不同,所以要进行音视频同步。由于人耳的听觉灵敏度是要高度视觉的。假如音频少一帧的话是能够明显感觉到的。但是视频少一帧是很难察觉到的。所以所以视频同步的关键是以音频播放为准,视频不断的去减少两者之间的相对播放时间。一、记录音频的相对播放时间1、声明变量clock(相对开始的播放时间),...原创 2019-06-15 14:02:46 · 911 阅读 · 0 评论 -
视频播放器--android端音频播放
之前已经完成了视频的播放,下面将完成音频的播放。一、音频解码1、首先在fFpeng类中会开启一个不断读取packet的子线程,并且把相应packet类型(视频类型,音频类型)存放到不同的音视频frame队列中。和之前视频播放一样,这里添加音频的代码。代码如下:void QbFFmpeg::start() { isPlaying = true; //视频开始播放 交给视...原创 2019-06-15 13:37:16 · 330 阅读 · 0 评论 -
视频播放器--android端视频播放
一、准备阶段开始之前,需要将FFmpeg集成到AS中,集成步骤可以参考之前的一一篇文章,链接地址linux如何编译ffmpeg,并集成到AS中。另外,需要额外依赖三个动态库libz.so(使用ffmpeg需要引入,这个软件包提供了用gzip和PKZIP压缩算法进行开发),libandroid.so(提供了视频渲染的窗口类ANativeWindow)和libOpenSLES.so(音频播放相关)...原创 2019-06-14 10:52:50 · 442 阅读 · 0 评论 -
直播--android端推流实现一
首先需要了解推流端需要采集两部分数据,视频和音频,视频是通过摄像头采集的。音频是通过麦克风采集的。对于android设备摄像头采集的数据是没有经过压缩的NV21数据(属于YUV420数据格式,需要了解两者区别的,查看链接:YUV与NV21),由于这样的数据没有经过压缩,数据量很大,想要传给服务器就需要对其进行压缩(编码),采用H264编码。要使用x264工具将NV21数据编码成H264(H264是...原创 2019-06-01 21:58:59 · 4131 阅读 · 0 评论 -
直播--android端推流实现二
了解本章内容之前,需要了解H.264编码原理。链接地址H.264编码原理上面讲到了如何将推流需要的库rtmpDump、x264集成到项目中,本节讲述视频推流实现,上一张推流的流程图:流程图看到,首先我们摄像头采集到的数据,会通过VideoChannel.cpp将NV21数据编码成I420数据。并将I420数据按照rtmp协议规则将数据封装成packet中,将packet放入队...原创 2019-06-01 21:58:15 · 1772 阅读 · 0 评论 -
android事件分发机制
android的事件分发机制可以分为3类:activity事件分发,viewGruop事件分发及子view事件分发。事件分发相关的三个方法:dispatchTouchEvent() onIterceptTouchEvent() onTouchEvent()其中onIterceptTouchEvent()方法仅存在于viewGroup中。下面通过源码的形式具体分析这三类是如何进行事件分发的...原创 2019-03-31 20:46:39 · 182 阅读 · 0 评论