android
csdn_Mew
吓成一坨兔子
展开
-
https抓包与防抓包
抓包工具CharlesFiddlerCharles使用下载PC端安装Charles根证书help–>SSLProxying–>Install Charles Root Ceriticate安装Charles根证书到手机help–>SSLProxying–>Install Charles Root Ceriticate on a Mobile Devic...原创 2020-02-01 00:56:39 · 9172 阅读 · 2 评论 -
Dex加固与反编译
编译与反编译编译将java代码转换为Dalvik字节码将res资源文件、AndroidManifest.xml等配置文件编译为二进制文件反编译将DEX文件转换为jar包或者Smali文件将二进制资源文件还原为资源源码文件编译与反编译是相对的过程,转换过程分别由编译器和反编译器实现。反编译工具ApkTooldex2jarjd-guiApkTool反编译Dex为sm...原创 2020-01-31 23:32:18 · 1934 阅读 · 0 评论 -
APK打包过程
APK构建打包过程通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)处理.aidl文件,生成对应的Java接口文件通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件通过dex命令,将.class文件和第三方库中的.class文件处理...原创 2020-01-31 22:51:16 · 488 阅读 · 0 评论 -
内存优化三
现象public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.la...原创 2020-01-31 17:02:13 · 165 阅读 · 0 评论 -
内存优化二
内存泄漏Handler内存泄漏分析public class MainActivity extends AppCompatActivity { private final int MESSAGE_WHAT = 10000; Handler handler = new Handler() { @Override public void handle...原创 2020-01-17 16:53:39 · 328 阅读 · 0 评论 -
内存优化一
Java虚拟机概念Java虚拟机是一台"抽象的计算机",它拥有自己的处理器,堆栈,寄存器及相应的指令系统;Java虚拟机屏蔽了与具体操作系统相关的平台信息,使得Java程序只需要生成在该虚拟机上运行的目标代码,就可以以在多平台上运行;虽然叫Java虚拟机,但在它之上运行的语言不仅有Java,还有Kotlin,Groovy,Scala等都可以运行;Java虚拟机执行流程Java虚拟机运行时...原创 2020-01-15 23:46:25 · 212 阅读 · 0 评论 -
UI渲染优化
CPU与GPU蓝色的Control为控制器,用于协调控制整个CPU的运行,包括取出指令,控制其它模块的运行等。橙色的ALU(Arithmetic Logic Unit)为算数逻辑单元,用于数学及逻辑运算;橙色的Cache和DRAM分别为缓存和RAM,用户存储信息。CPU控制器比较复杂,ALU数量较少。因此CPU擅长各种复杂的罗技运算,但是不擅长数学尤其是浮点计算。例如使用16进制表示颜...原创 2020-01-14 22:56:15 · 439 阅读 · 0 评论 -
启动APP的代码优化
启动APP时的问题在构建App时, 经常需要引入一些第三方的SDK,而项目业务越多,引用的第三方也越多,有些第三方会要求在Application的onCreate方法中对其初始化。 这意味着在application的onCreate方法中执行时间会被拉长,首个Activity布局的渲染时间也会相应地拉长。同理,如果我们在Activity的onCreate,onStart,onResume方法中...原创 2020-01-14 21:55:44 · 329 阅读 · 0 评论 -
启动APP时黑白屏的解决方案
黑白屏的原因当打开一个Activity时,如果这个Activity所属的应用还没有在运行,系统会为这个Activity所属的应用创建一个进程,但进程的创建与初始化都需要时间,在这个动作完成之前系统要做什么呢?如果没有任何反应的话,如果程序初始化的时间很长,用户可能还以为没有点到相应的位置。但此时所启动的程序还没初始化完,既无法显示程序,又不能停在原处不做任何动作,怎么办?这就有了Starting...原创 2020-01-13 23:24:04 · 4722 阅读 · 0 评论 -
IoC之手写运行时注入通用事件
通用事件注解@Target(ElementType.ANNOTATION_TYPE) // 本身自己就是注解,还可以作用域在 注解之上@Retention(RetentionPolicy.RUNTIME) // 运行时期public @interface OnBaseCommon { // todo 事件三要素1 订阅方式 setOnClickListener, setOnLo...原创 2020-01-09 16:55:07 · 189 阅读 · 0 评论 -
IoC之手写运行时注入点击事件
废话不多说,先写一个注解@Target(ElementType.METHOD) // 作用域在方法上@Retention(RetentionPolicy.RUNTIME) // 运行时期public @interface Click { int value();}然后写处理这个注解的方法 /** * 把布局里面的控件ID 和 Activity方法绑定起来,建...原创 2020-01-09 16:50:06 · 190 阅读 · 0 评论 -
IoC之手写运行时注入控件
前言上篇文章中,我们介绍了运行时注入布局,这篇文章我们将介绍如何在运行期注入控件,也就是运行期实例化控件。注入控件首先我们仍然需要一个注解,去获取需要在运行期实例化的变量及其id@Target(ElementType.FIELD) // 作用域我们字段上@Retention(RetentionPolicy.RUNTIME)public @interface BindView { ...原创 2020-01-09 16:47:44 · 193 阅读 · 0 评论 -
IoC之手写运行时注入布局
常规写法public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R....原创 2020-01-09 16:30:05 · 182 阅读 · 0 评论 -
Dagger2的简单使用及解析
Dagger2是什么Dagger2是一款基于Java注解来实现的完全在编译阶段完成依赖注入的开源库,主要用于模块间解耦、提高代码的健壮性和可维护性。Dagger2在编译阶段通过apt利用Java注解自动生成Java代码,然后结合手写的代码来自动帮我们完成依赖注入的工作。不用Dagger2的代码public class Student { String name = "liu"; ...原创 2020-01-09 16:24:34 · 440 阅读 · 0 评论 -
ButterKnife系列之手写实现
注解java-librarybuild.gradleapply plugin: 'java-library'dependencies { implementation fileTree(dir: 'libs', include: ['*.jar'])}// 中文乱码问题(错误: 编码GBK的不可映射字符)tasks.withType(JavaCompile) { o...原创 2020-01-07 20:10:15 · 437 阅读 · 1 评论 -
ButterKnife系列之简单使用和原理分析
ButterKnife的优势强大的View绑定和Click事 件处理功能,简化代码,提升开发效率方便的 处理Adapter里的ViewHolder绑定问题运行时不 会影响APP效率,使用配置方便代码清晰,可读性强ButterKnife与IoC的对比共同特点:同样实现了解耦的目的核心技术:运行时通过反射技术(reflect)VS注解处理器技术(APT)开发使用:两者几乎- -样...原创 2020-01-07 19:40:38 · 160 阅读 · 0 评论 -
RxJava系列之手写切换线程
切换线程在上游和下游之间增加切换线程的操作,如果手写map操作符明白的话, 这里就很简单。使上游执行在子线程的ObservableOnSubscribe的子类// 上游处理 异步线程的 Observable的子类 [给所有上游 切换异步线程]public class ObservableOnIO<T> implements ObservableOnSubscribe&l...原创 2020-01-07 17:43:31 · 331 阅读 · 0 评论 -
RxJava系列之手写map操作符
map操作符map操作符是变换操作符,将上游的数据经过变换交给下游。所以内部肯定需要对上游操作,也要对下游操作。Function变换的标准,可以将T变换成Rpublic interface Function<T, R> { public R apply(T t); // 变换的行为标准}ObservableMap负责与上游下游打交道的类。因为需要同时接收...原创 2020-01-07 16:47:24 · 341 阅读 · 0 评论 -
RxJava系列之手写just操作符
just操作符just操作符也是创建操作符,为了创建Observable。与create的区别是,just操作符内部自动发射事件,不需要像create操作符 那样手动发射事件。增加just操作符的Observable// todo 被观察者 上游public class Observable<T> { // 类声明的泛型T Int ObservableOnSubsc...原创 2020-01-07 14:14:21 · 433 阅读 · 0 评论 -
RxJava系列之手写create操作符增加泛型限定
可读、可写模式 与上限下限的区别如果有一个人类Person,有一个学生类Student,学生继承人,有一个职务类Job,继承学生 那么针对如下代码:class Person{}class Student extends Person{}class Job extends Student{}public void test(List<? extends Person> ...原创 2020-01-07 14:00:13 · 274 阅读 · 0 评论 -
RxJava系列之手写create操作符
create操作符用于创建上有被观察者Observable的静态方法。Observable// todo 被观察者 上游public class Observable<T> { // 类声明的泛型T Int ObservableOnSubscribe<T> source; private Observable(ObservableOnSubs...原创 2020-01-07 10:04:20 · 273 阅读 · 0 评论 -
RxJava系列之泛型高级
因为RxJava中大量使用了泛型,而且使用了高级特性,所以这里学习一下。泛型简单使用 List<String> list = new ArrayList(); list.add("A"); // list.add(6); // 编译期 就可以看到错误 String s = list.get(0);// 变量自动是String类型上...原创 2020-01-06 20:23:29 · 434 阅读 · 1 评论 -
RxJava系列之配合Retrofit
Retrofitretrofit是网络封装库,内部网络请求交由OkHttp来做的。本文中使用RxJava+Retrofit实现下面这样的需求:需求:1.请求服务器注册操作2.注册完成之后,更新注册UI3.马上去登录服务器操作4.登录完成之后,更新登录的UI定义网络请求接口public interface IRequestNetwork { // 请求注册 功能 tod...原创 2020-01-06 19:58:50 · 430 阅读 · 0 评论 -
RxJava系列之背压模式
背压模式背压模式的由来:RxJava1.X的时候,还没有背压模式, 我们的上游不停的发射,我们的下游处理不过来,就会照成内存泄漏RxJava2.X之后,增加背压模式,Observable Flowable(解决背压)Observable — > Flowable(解决背压)什么时候用Observable<—>Observer, 什么使用Flowable<—>...原创 2020-01-06 18:09:14 · 429 阅读 · 0 评论 -
RxJava系列之线程切换实战
线程切换前面的文章都是写的demo代码,本篇文章可以实战使用RxJava的方式加载网络图片。RxJava可以方便的设置上游和下游的执行线程,从而达到异步处理的作用。如何切换线程RxJava默认执行在主线程。如果需要切换上游执行线程,使用subscribeOn操作符。如果需要切换下游执行线程,使用observeOn操作符。 /** * todo 异步线程区域 * Sche...原创 2020-01-06 17:43:08 · 609 阅读 · 0 评论 -
RxJava系列之常用异常操作符
异常操作符异常操作符可以拦截到上游的onError事件,从而修改发射到下游的事件。主要分为两大类,可以拦截throws new Exception()的和不能拦截throws new Exception的。onErrorReturn1.能够接收e.onError, 2.如果接收到异常,会中断上游后续发射的所有事件 /** * onErrorReturn异常操作符:1.能...原创 2020-01-06 16:56:10 · 309 阅读 · 0 评论 -
RxJava系列之常用合并操作符
合并操作符合并操作符,顾名思义, 将多个被观察者发射的事件合并到一个观察者中接收。有两种方式,一种是用一个被观察者调用方法,加入另外一个被观察者。另一种是将多个被观察者合为一个被观察者。startWithstartWith合并操作符,属于第一类。将会先执行startWith传入的参数被观察者。 /** * startWith 合并操作符, 被观察者1.startWith(被观察者...原创 2020-01-06 16:04:13 · 568 阅读 · 0 评论 -
RxJava系列之常用条件操作符
条件操作符将上游发射的数据进行判断,下游的接收都是Boolean的。满足条件,下游接收到true,不满足条件,下游接收到false。all所有数据都满足条件,下游就接收到true,其中有一个不满足条件,就接收到false。 /** * all,如同 if 那样的功能 :全部为true,才是true,只要有一个为false,就是false * @param view ...原创 2020-01-06 15:33:01 · 349 阅读 · 0 评论 -
RxJava系列之常用过滤操作符
过滤操作符上篇文章中,我们学习了变换操作符。 过滤操作符顾名思义就是对数据的筛选与过滤,与变换操作符的位置相同,作用不同。filter如果过滤操作符的方法返回false,则过滤掉该条数据,返回true则不过滤该条数据。 /** * filter 过滤 * 需求:过滤掉 哪些不合格的奶粉,输出哪些合格的奶粉 * @param view */ ...原创 2020-01-06 15:16:29 · 260 阅读 · 0 评论 -
RxJava系列之常用变换操作符
变换操作符在上游发射的事件经过操作之后再发射给下游。相当于在上游与下游之间再做处理。例如map操作符的逻辑如下图所示:map /** * map 变换 操作符 * @param view */ public void r01(View view) { // 上游 Observable.just(1) // 发射 1...原创 2020-01-06 14:57:26 · 280 阅读 · 0 评论 -
RxJava系列之常用创建型操作符
什么是创建型操作符个人理解就是创建上游或者说被观察者或者说Observable对象的方法。名字起得那么高大上。createcreate操作符是最原始的,需要开发者手动发射事件。 /** * create 操作符 创建 Observable * @param view */ public void r01(View view) { // ...原创 2020-01-06 11:09:41 · 290 阅读 · 0 评论 -
RxJava系列之上游与下游
什么是上游和下游在RxJava中,我们将事件的起源称之为上游,事件的处理称之为下游。上游产生事件之后,发射给下游,下游接收到并请求。如下图所示:简单例子/** * 流程整理 1 * @param vieww */ public void r04(View vieww) { // 上游 Observable 被观察者 O...原创 2020-01-05 16:48:45 · 882 阅读 · 1 评论 -
RxJava系列之简介和观察者设计模式
RxJava简介响应式编程在介绍RxJava前,我们先聊聊响应式编程。那么什么是响应式编程呢?响应式编程是一种基于异步数据流概念的编程模式。数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一条流合并为一条新的流。响应式编程的一个关键概念是事件。事件可以被等待,可以触发过程,也可以触发其它事件。事件是唯一的以合适的方式将我们的现实世界映射到我们的软件中:如果屋里太热了我们...原创 2020-01-05 13:26:33 · 453 阅读 · 0 评论 -
Glide手写实现之复用池
为什么要用复用池Bitmap属于大对象,在频繁创建对象和回收对象时,会有内存抖动问题。为了解决这个问题,Glide中使用了复用池。在开辟新的Bitmap对象空间之前,从复用池中找寻是否有合适的内存空间可以直接使用。复用池仍然使用了LRU算法。BitmapPool复用池的标准接口// 复用池 标准public interface BitmapPool { /** * 存...原创 2020-01-05 02:07:56 · 657 阅读 · 0 评论 -
Glide手写实现之网络图片加载实现
图片加载理论分析(网络图片)前面几篇文章中,我们了解到Glide的三级缓存和生命周期与Activity的绑定。 本文章会把之前的三级缓存融合在一起,成为一套缓存策略。根据生命周期,调度缓存和释放缓存。理论上加载网络图片的时候,先要从缓存中获取,如果缓存中拿不到,再从网络中获取。网络中获取到的图片需要保存到缓存中,以备下次使用。RequestTargetEngine加载图片的引擎,先从活动缓存...原创 2020-01-05 01:00:52 · 495 阅读 · 0 评论 -
Glide手写实现之生命周期关联
生命周期关联Glide根据传入的上下文环境,比如Activity,FragmentActivity,关联到与之对应的生命周期回调方法。原理是在Activity或者FragmentActivity中添加一个空的Fragment,从而与Activity或者FragmentActivity的生命周期关联。但是传入Context的话, 没法进行生命周期的关联。Glidepublic class Gl...原创 2020-01-04 16:59:16 · 416 阅读 · 0 评论 -
Glide手写实现之磁盘缓存
磁盘缓存Glide中的磁盘缓存是三级缓存,也是最后一级缓存。缓存的内容直接写到磁盘中,存放的时间久,不会随着APP进程死亡而消失。如果磁盘缓存中没有,就会从网络中或者SD卡中获取资源了。同样使用的是Lru算法。虽然Google官方没有提供缓存到磁盘的LRU实现,但是GitHub上有一个开源项目实现了,而且得到了Google官方的认证,即J神写的DiskLruCache封装DiskLruCa...原创 2020-01-04 15:49:26 · 411 阅读 · 0 评论 -
Glide手写实现之内存缓存
内存缓存Glide中的内存缓存是二级缓存,当活动缓存中取不到资源的时候,再从内存缓存中取。内存缓存用的LRU算法缓存。其原理是当缓存已满再加入元素时最不常使用的元素会被移除。LRU算法LRU算法的原理比较简单,数据存储的数据结构为链表。当访问数据时,如缓存中有数据,则将该数据移动至链表的顶端;没有该数据则在顶端加入该数据,并移除链表中的低端的数据。LRUCacheAndroid的v4兼容...原创 2020-01-04 14:36:02 · 329 阅读 · 0 评论 -
Glide手写实现之活动缓存
活动缓存活动缓存是直接使用的缓存。回收机制:GC扫描的时候回收,移除容器(GC被动移除)(弱引用)容器管理方式:资源的封装 Key ----- (弱引用)手动移除的区分关闭线程ActiveCache/** * 活动缓存 -- 真正被使用的资源 */public class ActiveCache { // 容器 private Map<Str...原创 2020-01-04 11:09:12 · 707 阅读 · 0 评论 -
Glide手写实现之资源封装
封装资源封装资源的目的是为了给缓存使用方便管理。Key/** * 唯一的描述 */public class Key { private String key; // 例如:ac037ea49e34257dc5577d1796bb137dbaddc0e42a9dff051beee8ea457a4668 /** * sha256(https://cn.bing...原创 2020-01-04 11:06:09 · 477 阅读 · 0 评论