Lint代码检查工具
Lint代码检查工具背景在每个项目的开发过程中,或多或少都会存在一些属于项目自身的或通用的规定,它们的存在可能是为了规范代码,可能是为了避免某些BUG,也可能是因为特殊需求而不得不做的妥协。这些规则会被写在注释里、写在README里,亦或者被口口相传,然后很有可能在某一天被某一个新来的小伙子忽略并演变为线上BUG。
为了避免这种情况,我们需要更明显的提示。它需要覆盖范围广,在项目内编写的代码都应该能被检测到。它需要具有即时性,当代码写下的时,警告应该立刻出现。它具有需要强制性,在编译时或者代码提交时,如果检查到异常可以中断编译或禁止提交。那么,我们可以试试Lint。
Lint介绍Lint是Android Studio提供一个代码扫描和检查工具。Android Studio本身就自带了许多的Lint规则以帮助开发者规范的进行代码编写,同时它也开放了接口,开发者可以自定义Lint规则用于管理项目中不符合预期的代码。
主要API
Issue:表示一个Lint规则。
Detector:用于检测并报告代码中的Issue,每个Issue都要指定Detector。
Scope:声明Detect ...
编译ExoPlayer FFmpeg扩展
编译ExoPlayer FFmpeg扩展(NDK20、FFmpeg4.2)之所以需要这个扩展是因为做播放器的时候发现exoplayer不支持ac3音频,来来回回走了几趟弯路,终于搞定了,写下来记录一下
一、编译FFMPEG(Linux环境) 编译平台:ubuntu 16.04LTS
ffmpeg版本:release/4.2
ndk版本:android-ndk-r20b
下载ndk,我使用的google推荐的android-ndk-r20b,注意下载linux版本,下载后提取到文件夹。此处我的ndk文件夹为:/home/ye/ndk/android-ndk-r20b
clone ffmpeg,切换分支到release/4.2,同样是google推荐的4.2版本
git clone https://git.videolan.org/git/ffmpeg.git
git checkout release/4.2
打开ffmpeg所在文件夹,如我的文件夹是/home/ye/Project, ...
反编译、回编译、脱壳的简单测试
以前为了开发Xposed插件,对app进行过脱壳或通过其它工具查看源代码的等操作,这次想实现对app的反编译和回编译,这里记录一下测试过程。
注:一些快捷查看源代码的工具
apk中代码:Smali2JavaUI、AndroidKiller
dex中代码:jadx-gui
jar中代码:jd-gui
Manifest文件代码:AXMLPrinter2
一、可反编译及回编译APK用于未作加固处理及其它特殊处理的apk(测试apk“动漫之家2.7.017”)
1、工具apktool_2.4.0.jar、jdk
2、反编译apktool_2.4.0.jar d test.apk
反编译得到test文件夹,修改smali文件(IDEA安装java2smali插件,可直接将java转smali,方便测试修改)
3、回编译apktool_2.4.0.jar b test
test就是反编译出来的文件夹名字在test\dist目录下得到新的apk文件
4、生成签名文件keytool -genkey -alias abc.keystore -keyalg RSA -validity 20000 - ...
关于实现局域网内视频播放
在我开源的APP 弹弹play 概念版 中实现了局域网视频播放的功能,所以将相关功能抽离出来写了个Demo,并写了这篇介绍相关内容的文章。
Demo地址:https://github.com/xyoye/SmbPlayHelper
一、简述
需要实现局域网内视频播放,首要条件是能从局域网文件中拿到InputStream(A),这里局域网内文件浏览的库推荐使用jcifs-ng或smbj,介绍中Demo使用的是jcifs-ng。
由于普通播放器一般不能直接设置InputStream(A)作为播放源,但是播放器大都是能播放http链接的视频,所以转换一下思路,通过创建本地服务端接收播放器的http请求,将InputStream(A)内数据写回播放器,以此实现播放。
二、功能实现一、创建ServerSocket
获取本地可用的网络接口从中拿到IP。
设置端口,创建ServerSocket。
所以在接收到请求后,会得到一个Socket,在新线程中处理该Sockt。
二、处理Socket
通过从Socket中拿到InputStream(B),将其转换为BufferedIn ...
Java垃圾收集算法
首先需要了解垃圾标记算法
垃圾标记算法,内部分为两种算法:引用标记算法、根搜索算法
1)引用标记算法
标记对象的引用,当无引用时,即为垃圾。
缺点:在互相引用的时候会导致无法回收。
2)根搜索算法
选定根节点,相当于所有引用的祖先,当子节点失去与父节点的引用,则子节点间无论有多少引用,都无法到达根节点,即为垃圾。
Java内部垃圾回收主要采用:分代回收算法
内部包括:标记清除算法、复制算法、标记压缩算法
1)标记清除算法
标记可清除的对象,回收标记的对象。
缺点:标记与回收效率不高,产生大量内存碎片,导致没有连续的内存分配给大对象,从而再次引起垃圾回收
2)复制算法
将内存区域分为两半,每次只使用其中一半,在回收时,将使用的一半中存活对象复制到未使用的一半中(我更倾向于表达为移动),再回收使用的一半中可回收的对象。
缺点:将内存分为两半,直接减少了可使用的内存。
3)标记压缩算法
与标记清除算法类似,但是在回收标记对象后,将存活对象压缩到一端,将存活对象内存边缘外的对象回收。
分代回收算法中将内存区域 ...
关于阻止手机息屏休眠的一些尝试
背景一个后台通过gps采集位置,录音,并将位置上传至服务器的程序,手机息屏后导致cpu休眠,功能无法正常执行。
尝试过的方法1、将任务放在service中进行,且为了适配Android8.0,并提高程序优先级,开启通知,作为前台服务运行,无效
2、开启weaklock锁,禁止cpu休眠,由于Doze的引入6.0后无效,在8.0测试时确实无效,未测试6.0前是否有效。
3、忽略省电白名单。有提示是否加入省电白名单,但加入后无效,并在手机设置-电源管理-省电白名单中未加入该白名单,猜测是由于不同厂家的rom导致无法加入该白名单
4、手动将应用加入手机设置-电源管理-省电白名单,测试后有效,在息屏后gps、录音、网络也能正常运行。
其它未测试的方法1、后台循环播放一段无声音乐,个人认为可行。但是与gps、录音、网络加在一起耗电量过大,而且录音与播放音乐不知是否有冲突,有时间会去尝试该方法。
2、root手机,将应用加入省电白名单,root适配范围太小,不适于大规模使用,特殊情况下有用。
代码1、weaklock锁
//权限
<uses-permission android:name=& ...
Android25 模拟器Root
为了在模拟器上研究一个xposed项目不得不尝试对模拟器进行root,网上看了一些教程,在尝试之后发现总是没有权限去写入su文件,后面在stackflow看了一个回答,结合前面的经历,终于搞定了。
一、工具需要准备的工具:
1、SuperSU app 2.82
2、SR5-SuperSU-v2.78.zip (密码:6phd)
3、Android Studio 及 Android7.1.1的模拟器
4、配好的adb环境变量
二、流程第一步通过Android Studio打开模拟器,在模拟器中安装第一个软件SuperSu。这个SuperSu就是用来授权的软件,安装后打不打开都无所谓,打开也不能用先。
第二步到你的的sdk安装目录下打开tools文件夹,按住shift+鼠标右键选择:在此处打开命令窗口,打开终端后输入:emulator.exe –avd {你的模拟器名称} –writable-system
例:emulator.exe –avd A25 –writable-system
输入之后显示如下,之后就不用管这个了终端了:
第三步解压第二个文件后找到你模拟器对应的内核的文件 ...
Handler运行机制源码解析
Handler是Android中用于处理线程中消息循环的机制,在一般的使用中,我们总是以Message作为消息载体,通过Handler发送处理消息,但是只是用还不够,我们还得知道它具体是怎么实现的,因此本文梳理了一下消息循环流程中Handler的具体实现。
1、主角介绍①Handler:发送消息、回调处理消息
②MessageQueue:按顺序存储消息
③Looper:从消息队列取出消息通知Handler处理
④Message:存储消息
2、一般用法
3、流程概要首先,我们把这个流程比作寄快递,Handler作为一个普通人,现在他要在北京Thread1处理业务,但是必须要在上海Thread2将东西送过来后才开始,所以它在上海Thread2将快递Message送到sendMessage()快递仓库MessageQueue,这个时候假如快递公司Looper里没有处理这条线路业务的小组,就开始组建prepare()专门送这条线路的业务小组,组建完成后开始让员工从仓库按顺序取件next(),并开始发快递loop(),当快递送到北京Thread1时Handler手中开始处理快递业务handle ...
Glide4.6.1 源码心得
Glide是一款优秀的图片加载工具,使用起来也比较简单方便,为了更深入的学习,所以就去研究了一下glide的源码。
1、一般用法Glide.with(Activity).load(URL).into(ImageView);
2、with方法Glide中with方法一共有六个重载方法,传入值分别为:Context,Activity,FragmentActivity,app.Fragment,v4.Fragment,View类。
在with方法内部调用了get方法,这个方法是用于绑定Glide的生命周期。
get方法内可以看到一个判断:是否在主线程,假如不是将Glide与APP的生命周期绑定在一起。而假如是在主线程,那么就会在activity中添加一个隐藏的fragment,用以判断activity的生命周期。
3、load方法通过with方法后将会得到一个RequestManager类,在这个类中提供了load方法。load方法共有九个重载方法传入值分别为:Bitmap,Drawable,String,Uri,File,Integer,URL、byte[],Object类。通过这些方 ...