自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

风语的专栏

仗剑天下,快意恩仇

  • 博客(68)
  • 资源 (9)
  • 收藏
  • 关注

原创 移动端算法加速总结

性能加速,即对于给定的输入,用更短的时间获得我们想要的输出。总的来说有两个思路:降低计算量提高计算速度。各种优化技术基本上都是围绕这两点展开的。降低计算量优化算法或模型,使得用更少的计算量就可以达到同样的效果简化算法或模型,使得在牺牲部分准确度或效果的情况下速度能有大幅提升,看应用场景算法本身不变,优化实现。或将算法中可能存在的重复计算抽离出来,结果进行复用,或其它...

2018-09-04 18:03:44 1698 1

原创 关于Android端相机应用涉及到的技术

目前AI视觉以及短视频相关的应用都和相机有关,涉及到相机的调用,Surface渲染,视频录制等功能,这里做了一个Demo项目,基本包含了Android相机应用涉及的所有技术。https://github.com/dingjikerbo/Android-CameraAndroid Camera Demos一、相机预览序号项目名称内容简介1GLSurfacePrevi...

2018-12-28 20:47:32 572

原创 VLC卡死内存溢出解决

SurfaceTexture不直接显示图像流,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。首先,SurfaceTexture从图像流(来自Camera预览...

2018-11-23 21:08:50 8549

原创 NEON优化——OpenCV WarpAffine最近邻

warpAffine一种典型的应用场景是将camera拍到的图像中人脸抠出来,通过变换输出一张正脸,然后再做一些人脸识别,关键点检测之类的运算。所以通常是输入尺寸固定,输出尺寸也固定,变的是转换矩阵。最近邻的优势是计算量小,速度较快,问题是放大的情况下锯齿较明显,对于通常是缩小的应用场景最近邻是比较合适的,如果希望在所有的场景下有相对更好的效果,可以考虑双线性。算法要点warpAffine和...

2018-11-23 21:07:30 2777 1

原创 NEON优化——OpenCV WarpAffine双线性插值

算法要点warpAffine双线性插值和最近邻的区别根据目标图像的某点坐标算出原始图像对应的点坐标后,最近邻是向下取整,双线性插值需要获得相邻的四个点坐标以及纵横方向的权重最近邻直接拷贝原始图像点即可,双线性插值需要横竖加权很显然计算量要比最近邻大一些,但是效果会更好,对于放大的情况没有明显的锯齿。优化要点在计算偏移时基本和最近邻相同,同样要考虑异常情况和越界读的问题,另外要注意...

2018-11-23 21:04:34 3023

原创 NEON优化——OpenCV Resize双线性插值

算法要点一、基本原理具体原理可以自行搜索,这里只大致描述一下,目标图像上某一个点按比例映射到原始图像上某一点,不过通常计算得到的原始点坐标不是整数,最近邻的做法是向下取整,而双线性差值的做法是取与该坐标最接近的上下左右四个点来线性加权,在放大的时候不会像最近邻那样锯齿严重,但是计算量会大不少。这里要注意的是加权分为两个维度,横向和纵向。此外,边界的处理也要注意。二、优化思路这里核心的优化思...

2018-11-23 20:59:50 7141 5

原创 Android Camera源码分析

回顾这半年做的项目基本都跟Camera有关,从手势识别控制空调,到人脸识别的门禁,都是围绕相机的数据处理和渲染。这里相机不限于本地的相机,还包括远程的RTSP相机,要将数据流拉到本地进行渲染。这两天好好读了一下Camera的源码,大概理清了整体架构,总结了一下,其实没多少东西,Android的各个模块都差不多,都是有个系统服务,然后Java封一层,Native封一层,Java层和Native层的...

2018-11-23 20:55:40 3609

原创 Android视觉应用性能优化

计算机视觉在移动端的应用,典型的如手势识别,人脸识别,流程都差不多,都是利用移动端的相机采集数据,丢给算法层,根据识别的结果来做一些业务,中间可能还要做一些图形的渲染。本文主要讨论这中间涉及到的一些问题以及优化的思路,算是对过往工作的总结吧。大致问题有以下五点:一,相机采集数据的格式是NV21,而算法层所需的格式是RGB,这中间需要转换,对于每秒30帧,每帧1920*1080的图像转换的耗时还...

2018-11-23 20:50:05 325

原创 Android BufferQueue原理分析

在Android中,BufferQueue是Surface实现本地窗口的关键,驻留在SurfaceFlinger进程中进行服务,下面从BufferQueue的结构开始分析,class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer, ...

2018-11-23 20:48:25 4564 1

原创 从Camera源码看如何从Jni回调到Java层

通常设备层有数据或事件要通知到应用层是通过回调来完成的,可以采用的方式是直接调用java层类静态函数,或者调用java层某个对象的普通函数,涉及几个问题:1,内存泄露,引用问题2,多线程问题首先研究一下Camera的实现,首先打开Camera返回一个Camera对象,setPreviewCallback传入了一个callback,这个callback没有传入jni层,只是在Camera对象...

2018-11-23 20:45:15 939

原创 VLC RTSP视频播放终极解决方案

VLC播放RTSP视频流遇到的问题摄像头是RTSP协议的,需要在Android端实时显示摄像头视频流,这里采用了开源的VLC播放器,可能会有如下需求: 一、有截屏的需求 二、有屏幕录制的需求 三、视频本来是横的,但是现在要竖屏显示,如何旋转视频,另外旋转后视频会拉伸,因此需要截取一段显示 四、显示的视频可能需要做额外处理,比如识别出人脸后框出来先说说直接用VLC播

2017-10-12 20:23:27 17318 3

原创 关于Grafika的RecordFboActivity

这个是为了展示通过FBO录制视频的三种方式,先总结一下,采用SurfaceView加单个EGLContext,两个Surface,一个是Display Surface,另一个是Video Surface。三种方式如下:一、多次绘制,即先切到Display Surface绘制,然后再切到Video Surface绘制,绘制完后swapBuffer推送生效。二、BlitFrameBuffer,先绘制到D

2017-08-15 17:18:45 656

原创 采用Parcelable实现对象的深度拷贝

public class ParcelHelper { public static <T> T copy(Parcelable input) { Parcel parcel = null; try { parcel = Parcel.obtain(); parcel.writeParcelable(input, 0)

2017-08-03 11:52:58 3142

原创 ProgressButton的实现

一向对UI不是太感兴趣,不过项目中遇到了还是得去做,做这个ProgressButton还是费了不少功夫,不过效果还可以,这里先记下,以后可能还会用到。只贴代码,原理就不多说了。public class ProgressButton extends Button { public static final int MODE_BUTTON = 0; public static final i

2017-03-30 10:21:10 1387

原创 谈Android PowerManager的Hook技术

在插件中,需要禁止插件调用系统原生接口持有WakeLock,Hook技术是不错的解决方案。通过阅读系统源码,可以了解到PowerManager持有WakeLock操作最后都通过Binder跨进程调到系统服务中,我们只要拦截这个Binder的所有调用即可。思路是先通过反射拿到这个IPowerManager的Binder,然后动态生成该Binder的代理对象,再覆盖原有的Binder即可。public

2017-03-29 11:20:15 1432 5

原创 getSystemService的奇怪问题

先看如下代码,这两个PowerManager不是同一个对象,PowerManager manager = (PowerManager) getSystemService(POWER_SERVICE);PowerManager manager2 = (PowerManager)getApplicationContext().getSystemService(POWER_SERVICE);只能从内核源

2017-03-28 20:45:22 2195

转载 用happen-before规则重新审视DCL

编写Java多线程程序一直以来都是一件十分困难的事,多线程程序的bug很难测试,DCL(Double Check Lock)就是一个典型,因此对多线程安全的理论分析就显得十分重要,当然这决不是说对多线程程序的测试就是不必要的。传统上,对多线程程序的分析是通过分析操作之间可能的执行先后顺序,然而程序执行顺序十分复杂,它与硬件系统架构,编译器,缓存以及虚拟机的实现都有着很大的关系。仅仅为了分析多线程程

2017-03-16 17:55:09 520

转载 Java并发编程:volatile关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来

2017-03-16 17:17:23 1179

原创 Retrofit源码解析

Retrofit代码不多,设计得很精巧,非常值得借鉴。首先看Retrofit是如何创建的:public <T> T create(final Class<T> service) { return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new Invoc

2017-01-16 12:02:23 687

原创 Android蓝牙源码分析——GKI定时器

GKI定时器初始化在gki_ulinux.c中的GKI_init中,如下:void GKI_init(void){ ...... struct sigevent sigevent; memset(&sigevent, 0, sizeof(sigevent)); sigevent.sigev_notify = SIGEV_THREAD; sigevent.sig

2016-09-08 13:02:33 2526 1

原创 Android蓝牙源码分析——Gatt的Connection ID

我们注意到GattService中的所有GATT操作都会带两个参数,一个是clientIf,另一个是address,拿到这两个参数后,都会调用Integer connId = mClientMap.connIdByAddress(clientIf, address);获取对应的connId,然后之后的操作都是以这个connId为Key。我们来看看这个connId的生成过程,在ContextMap中,

2016-09-04 17:21:48 2989

原创 Android蓝牙源码分析——Gatt写设备

BluetoothGatt中的writeCharacteristic的实现在GattService中,如下:void writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, byte[] value) { gattClientWriteCharacteristicNat

2016-09-03 18:36:43 5207

原创 Android蓝牙源码分析——BTA层消息分发

这里BTA是Bluetooth Application的缩写,从上层下来的请求都要经过这个BTA层,通过发送消息的方式将请求丢到BTA层中处理。这个发送消息的函数定义在bta_sys_main.c中,如下:void bta_sys_sendmsg(void *p_msg){ GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_ms

2016-09-03 18:15:46 5625

原创 Android BLE设备蓝牙通信框架BluetoothKit

这个框架源于目前一个智能家居APP项目,是蓝牙部分基础模块,用于蓝牙设备扫描、连接、通知等。由于目前接入的蓝牙设备大多为低功耗蓝牙设备,所以本框架暂不支持经典蓝牙的连接。项目地址: https://github.com/dingjikerbo/BluetoothKit先介绍本框架的特点: 一、支持经典蓝牙和BLE蓝牙混合扫描,支持自定义扫描策略 作为智能家居平台,接入的设备包括经典蓝牙和BLE,

2016-08-29 11:49:17 26660 64

原创 Android蓝牙之Gatt Hook

许多人可能对Hook技术有些陌生,其实从字面意思上理解这就类似一个钩子,挂在了系统中的某些地方,然后当执行流程经过该处时会被勾住,可以选择放行或截获,或做点手脚偷偷改改参数,或记录日志,或检查权限,或post到别的上下文去执行,应用场景还挺多。本文会重点讨论蓝牙相关的Hook,要全局监测所有BLE蓝牙设备的操作,对于不那么活跃的设备我们会断开连接并释放资源,毕竟蓝牙通信信道是有限的。那么如何全局监测

2016-08-27 16:32:04 3391 1

原创 谈动态代理在解决内存泄露中的妙用

内存泄露在Android开发中很常见,每次产品上线之前都要集中解决内存泄露问题,有的问题很明显,有的藏的很深,解决起来要颇费一番功夫,不过总的思路都是一样,就是切断引用链,让资源在该释放的时候能被及时释放。我们先看一个内存泄露的案例:public class ServiceManager { public static void bindService(final BindResponse r

2016-08-26 21:21:44 3367 3

原创 Android蓝牙源码分析——Gatt连接(一)

本文将重点描述Android蓝牙GATT连接的大致流程,不会过多地纠缠代码细节,只为了从架构上梳理清楚,为接下来深入研究底层机制奠定一个宏观认识。 首先建立GATT连接前,我们通常要扫描蓝牙设备,获得设备的BluetoothDevice对象,然后调用connectGatt去建立GATT连接并等待连接状态回调,接下来我们就开始分析这一过程,首先看看connectGatt的实现:public Bl

2016-08-21 19:32:33 14712 5

原创 Android蓝牙源码分析——关于GKI

首先以gki模块的初始化为入口,在gki_ulinux.c中,如下: void GKI_init(void){ pthread_mutexattr_t attr; tGKI_OS *p_os; memset (&gki_cb, 0, sizeof (gki_cb)); gki_buffer_init(); gki_timers_init

2016-08-19 09:13:23 5842

原创 Android蓝牙源码分析——StateMachine状态机

StateMachine有自己单独的工作线程,protected StateMachine(String name) { mSmThread = new HandlerThread(name); mSmThread.start(); Looper looper = mSmThread.getLooper(); initStateMachine(name, looper)

2016-08-18 10:19:46 3904

原创 一个让我很无语的bug

被一个诡异的bug折腾了半天,当找到原因时哭笑不得。先看如下代码,大家分析一下打出来的会是什么:public class TestDebug { private static HashMap<String, BleDeviceProp> mPropCache = new HashMap<String, BleDeviceProp>(); public static void main(S

2016-05-12 20:04:05 1204 1

原创 一个关于Java的装箱与拆箱的bug

先看如下代码:public class TestBoxing { public static void main(String[] args) { int result = getProp("hello", new IPropGetter<Integer>() { @Override public Integer getProp(B

2016-05-11 10:48:12 969

原创 由两个bug引发的对Java类加载时机的思考

有一个单例类是这么写的:```Java public class BluetoothManager {private static BluetoothManager sInstance;public static BluetoothManager getInstance() { if (sInstance == null) { synchronized (Bluetooth

2016-05-07 19:00:36 1729 1

原创 谈动态代理在Android插件中的一些用法

我们为设备的插件提供了一系列接口,现在想记录下每个接口的调用情况,通常的做法是在每一个接口函数里都加上一堆上报的代码,这不是不可以,只是有些麻烦了,以后接口里每新增一个函数,就得记得加上上报,对于我这种记性不好的人来说,忘加的概率很大,所以如果有一劳永逸的办法那就好了,以后新增函数都会自动上报。先给出当前接口的形式,如下:public abstract class AbsBluetoothManag

2016-04-27 15:15:22 1742

原创 将模块service化的好处

蓝牙的所有操作最好都封装成一个service,好处是相对独立,作为一个service组件,可以指定所运行的进程,所有实现彻底和外部解耦,不管是同进程还是跨进程调用对外接口是不变的。因为APP中可能拆分成多个进程,这些进程对service的访问是统一的,不管和service是不是在同一个进程。另外放在一个service里可以保持数据只有一个操作对象,调用方来自多个进程,但是最后操作数据的只有servi

2016-03-09 08:04:38 1807

原创 Android热修复技术总结

这两年Android热修复是个挺时髦的东西,基本分为两派,一个是Hook虚拟机的,一个是Hook ClassLoader的。本文就来聊聊这两类方案,算是我自己的理解了。先说说Hook虚拟机的,这个技术源于国外的Xposed,又被阿里发扬光大,总体来说是个逼格很高的技术。将Java的函数在虚拟机层面改成一个Native函数,之后这个函数的走向就完全由我们来控制了,我们可以将其指向一个我们精心设计的Na

2016-03-06 20:00:59 1635

原创 关于Android MultiDex的问题

这段时间研究了一下Android MultiDex,这个东西乍看起来很简单,其实涉及到很多东西,本文就来讲讲这个,想到哪就说到哪。分包主要是因为包太大了,低端手机安装可能会失败,或者Dex加载的时候会崩溃,所以分成多个包,跟启动相关的放在主Dex,其余的不那么紧急的放在副Dex,然后启动的时候去动态加载。首先来看看主Dex,所谓跟启动相关的主要就是四大组件,所以四大组件直接引用到的类都要放在主Dex

2016-03-06 19:09:05 4847

原创 关于跨进程的观察者模式

记得以前面试别人时,我总喜欢问观察者模式分别在跨线程,跨进程,跨设备时该如何实现?印象中没几个人能完全答上来,而本文要讨论的就是跨进程的观察者模式。观察者模式通常就是注册回调到要观察的对象,当观察者和被观察者不在一个进程,回调就要跨进程传递。据我所知,Android中能跨进程传递的除了数据之外,就只有Binder了,所以这个回调要以Binder的形式跨进程传输。观察者传入回调的 Stub,被观

2016-02-28 09:31:13 2882

原创 一件挺有意思的事,关于数据校验

说个有意思的事,我妈晚上打电话向我求助,说她请了个人帮他收账,问我有不有什么办法能让她知道哪些账收回来了,哪些没有收回来。我一听就笑了,你要收哪些账都一条条列出来,收回来一笔就用红笔划掉,最后没有划掉的不就是没收回来的么。她说不行,因为收账的人和她一起办公的,可能会趁她不注意偷偷地用红笔划掉。这还真是个事,我说你用电脑记,给电脑上个密码不就行了,她嫌太麻烦。我又说你给本子锁在抽屉里吧,她说这样像防

2016-02-17 11:09:13 1196

原创 如何拦截Activity的启动(二)

本文我们将以一个工程为例,验证Hook Activity的可行性。我们的目标如下: - 指定插件Apk路径,启动插件 - 插件内部可启动Activity - 插件可作为独立App启动首先新建插件工程,和正常APP一般无二,没有任何特别的地方。所有的Activity都是从android.app.Activity继承,可以安装并运行。接下来新建宿主工程,并将插件Apk用adb push到宿主

2016-02-16 18:21:11 2648 2

原创 关于Handler的拦截

为什么要Hook Handler?Android系统中存在大量Handler,我们要改变系统的某些行为就需要Hook掉一些关键节点的Handler,为此,我们要清楚Handler的工作原理。先做一个实验来看看Hook Handler的效果,如下:public class MainActivity extends Activity { private Button mBtnShow; p

2016-02-16 11:14:22 2704

android热修复工程1

工程对应 http://blog.csdn.net/dingjikerbo/article/details/50448145

2016-01-03

WebViewTransformer

WebView高级用法,爬取网页,抽取标签,生成本地自定义的网页内容并用WebView加载

2015-08-18

C语言实现的网络爬虫

C语言实现的网络爬虫,各位感兴趣的话可以参考参考,用到了多线程、epoll等技术

2012-06-20

C语言功能接口库

C语言实现的各类功能接口,如命令行解析,内存管理器,调试接口,防御性输入处理接口等

2012-06-20

C语言实现的文件夹加密

C语言实现的文件夹加密程序,可以递归遍历目录,并对文件进行加密解密

2012-06-20

C语言实现的文件存储引擎

C语言实现的文件存储引擎,用到了很多高级的编程思想

2012-06-20

C语言删除注释程序

C语言实现的,可以自动删除程序中的注释,程序可读性非常好

2012-06-20

用C语言实现的计算器(支持复杂运算)

用C语言实现的计算器(支持复杂运算),代码可读性很强

2012-06-20

极其强大的C语言学生成绩管理系统(3000行代码)

这是你可以在网上找到的用C写的最强大的学生成绩管理系统,功能部分代码有3000行,附上设计报告,详细阐述了用到的各种编程技术和思想

2012-06-20

空空如也

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

TA关注的人

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