- 博客(80)
- 收藏
- 关注
原创 App流畅度优化:利用字节码插桩实现一个快速排查高耗时方法的工具
我们产线的主流程页面中有几个比较复杂的页面在版本迭代中流畅度频繁出现反复,经常由于开发的不注意导致变卡,主要是对流畅度缺少必要的监控和可持续的优化手段,这个系列是对上半年实践App流畅度监控、优化过程中的一点总结,希望可以给需要的同学一点小参考。当然App内存上的优化,尽量减少内存抖动也能显著提升流畅度,内存优化方面可以参考之前的文章:实践App...
2019-10-24 13:48:51
2751
原创 Android网络系列(一):关于计算机网络的一些基础
网络一直是项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架。从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用的工具类,到后来Google开源的比较完善丰富的Volley,再到如今比较流行的Okhttp、Retrofit。他们之间存在异同,这个系列主要想通过对网络基础知识、Android网...
2018-07-28 14:06:00
1107
1
原创 实践App内存优化:如何有序地做内存分析与优化
由于项目里之前线上版本出现过一定比例的OOM,虽然比例并不大,但是还是暴露了一定的问题,所以打算对我们App分为几个步骤进行内存分析和优化,当然内存的优化是个长期的过程,不是一两个版本的事,每个版本都需要收集线上内存数据进行监控以及分析。 版本迭代过程中,内存增长过快,不仅会导致一定概率的OOM,运行时若出现内存抖动,导致频繁GC,则会对App的流畅度以及用户体验造成很大影响。本文主...
2018-06-12 23:13:25
1117
原创 自定义View:View的Measure测量过程解析
    相信绝大多数Android开发者都有自定义View来满足各种各样需求的经历,也知道一个View的绘制展示要经过measure、layout、draw三大流程,三者中measure的过程相比是稍微复杂一点点的。这篇文章作为一个Android基础的分享,分享一下view/viewGroup measure的过程,view/viewGroup是如何通过me...
2018-04-16 22:59:33
322
原创 ReactNative中如何使用自定义的Iconfont图标
在App包的构成中图片资源是比较占大小的,所以我们可以利用Iconfont来替代原来的png或者jpg单色图标,iconfont的优点是占Size小、支持任意大小不失真、支持任意颜色设置、平台化管理icon等等。 当App项目的大小达到一定规模时,App包的Size也会随之增大,这个时候我们一般会对App包的Size做分析优化来达到减少包大小...
2018-04-07 08:37:28
8384
2
原创 RecyclerView封装与优化
最近优化了项目里的列表展示,顺便对RecyclerView的使用做了重新的封装,目的是当列表的需求比较复杂的时候,依然能够保持逻辑的清晰和解耦,同时通过封装来使复杂列表的性能得到一定的保证。 当然如果是非常简单的列表的话,其实Android原生的RecyclerView加上Adapter就已经比较便捷了,没有必要去做过度的封装了。项目GitHub地...
2018-03-30 01:10:26
1020
转载 android性能分析之Systrace的使用
一、概述保证系统流畅度,也就是保证系统能连续不间断地提供每秒60帧的运行状态。当出现掉帧时(也可称为Jank),需要知道当前整个系统所处的状态,systrace便是最佳的选择,它能手机检测Android系统各个组件随着时间的运行状态,并能提示该如何有效地修复问题,接下来说说systrace如何使用以及如何解读。二、Systrace2.1 使用DDMS启动Trace:
2017-10-15 17:54:45
1241
转载 加快apk的构建速度,如何把编译时间从130秒降到17秒
公司的项目代码比较多,每次调试改动java文件后要将近2分钟才能跑起来,实在受不了。在网上找了一大堆配置参数也没有很明显的效果, 尝试使用instant run效果也不怎么样,然后又尝试使用freeline编译速度还可以但是不稳定,每次失败后全量编译很耗费时间,既然没有好的方案就自己尝试做。https://github.com/typ0520/fastdex注: 本文所有的代码、文
2017-03-18 16:24:33
2843
2
转载 利用git submodule实现组件化模块分库
在開發的過程中我們的項目可能會引用其他的版本庫中的代碼, 例如公司已經累積了一套公用的函式庫, 被多個項目調用; 很顯然地, 不能把公用函式庫的文件直接放到我們開發中的項目中, 這樣不但項目的冗餘, 也增加維護的難度, 無疑是替自己找麻煩.這時候我們就可以使用Git中submodule功能, 來管理我們的子模版, 在這裡我們配合使用GUI SourceTree(以下就簡稱ST吧), 以下
2017-03-14 00:26:17
1631
转载 Android 组件化开发原理和配置
在Application的不断发展过程中,我们开发者要不断地增加新特性。更多的代码就意味着更长的build时间和更长的增量build时间。在工程较大的项目中,build时间要占到10%~15%的工作时间。这不仅是浪费时间,也是测试驱动工作方式(TDD)比较困难的原因。把Application分成多个modules可以解决这个问题。在根据功能、层级或者其他方式进行module切分Applic
2017-02-15 15:10:33
1324
转载 关于Java中枚举Enum的深入剖析
在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定。Java也不例外。Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析。什么是EnumEnum是自Java 5 引入的特性,用来方便Java开发者实现枚举应用。一个简单的Enum使用如下。123456789101112// Col
2017-01-06 01:28:16
632
原创 Volley源码解析
尊重原创,转载请注明出处,谢谢 很早就想写篇Volley源码解析的文章,但是写文章,特别是写源码解析的文章其实是需要决心的,也是需要时间的,因为你需要把你老早就看过的代码重新理一遍,然后加上注释,然后解析,继上一次写了个Volley的引子后,过去也有一段时间了,终于可以抽出一个周末下午的时间来写一下了,希望对需要的朋友有用的,另外,Volley的源码写的十分出色,可拓展性方面非常强,
2016-12-18 18:59:35
329
原创 MultiDex工作原理
看这篇文章前可以先看一下了解一下上篇:ClassLoader的工作原理(Java中和Andriod中的一些区别)没有引入MultiDex之前,整个app里就一个dex,对于这个dex的加载在安装的时候就加载好了,引入multidex之后,第一个dex依然是在安装的时候就加载好了,而第二个以及之后的dex则是在application里面的attachBaseContext()里面调用Mu
2016-12-14 12:21:58
2789
转载 ClassLoader的工作原理(Java中和Andriod中的一些区别)
早期使用过 Eclipse 等 Java 编写的软件的同学可能比较熟悉,Eclipse 可以加载许多第三方的插件(或者叫扩展),这就是动态加载。这些插件大多是一些 Jar 包,而使用插件其实就是动态加载 Jar 包里的 Class 进行工作。这其实非常好理解,Java 代码都是写在 Class 里面的,程序运行在虚拟机上时,虚拟机需要把需要的 Class 加载进来才能创建实例对象并工作,而完成这一
2016-12-14 11:18:17
1451
转载 Gradle入门
随着Android Studio越来越完善,更多的开发者舍弃掉Eclipse。但是新的IDE与以往的Eclipse有很大区别,这导致部分开发者望而却步,其中一个大家觉得比较麻烦的是Android Studio采用的新的构建系统,gradle。那么这篇文章我将对gradle进行一个简单介绍(主要讲gradle配合Android Studio的使用),希望帮助大家熟悉gradle。一. gra
2016-12-09 16:33:11
307
转载 SSL工作原理
公钥和私钥 一直以来对公钥和私钥都理解得不是很透彻,感觉到模棱两可。今天在网上找了半天,通过查看对这个密钥对的理解,总算弄清楚了。 公钥和私钥就是俗称的不对称加密方式,是从以前的对称加密(使用用户名与密码)方式的提高。用电子邮件的方式说明一下原理。 使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的: 1. 我发送给你的内容必须加密
2016-12-08 21:28:33
582
转载 Gradle详解
原文 http://www.infoq.com/cn/articles/android-in-depth-gradleGradle是当前非常“劲爆”的构建工具。本篇文章就是专为讲解Gradle而来。介绍Gradle之前,先说点题外话。一、题外话说实话,我在索尼工作的时候,就见过Gradle。但是当时我一直不知道这是什么东西。而且索尼工具组的工程师还将其和A
2016-10-23 18:24:50
1206
原创 Volley源码解析(准备阶段)--了解volley
网络请求一直是项目里比较重头戏的一部分,目前市面上也有许多比较成熟的网络请求封装库,使我们项目里的网络请求变得越来越方便,由于公司项目里用到的网络请求框架是Volley,所以打算从源码的角度解析一下Volley,以便更好的使用它,今天首先来了解一下Volley. Volley是Google在2013的I/O大会上推出的推出的 Android 异步网络请求框架和图片加载框架,
2016-09-04 17:28:16
367
原创 Android网络请求处理异步回调风险方案
尊重原创,转载请标明出处http://blog.youkuaiyun.com/zcxwww 我们都知道网络请求是异步的,所以就存在异步回调风险,具体来说,就是发出网络请求后,由于各种原因,如果view被回收,这时候执行回调函数就会因为找不到view而报空指针异常导致crash,而这种异步回调在我们程序中无处不在,不仅是网络请求,本地的异步任务,或者动画等都存在这种风险。可见如果不对异步回调
2016-09-04 12:17:51
4975
转载 解析ButterKnife实现原理
大部分Android开发应该都知道@JakeWharton 大神的ButterKnife注解库,使用这个库我们可以不用写很多无聊的findViewById()和setOnClickListener()等代码 ButterKnife项目的主页在这里:http://jakewharton.github.io/butterknife/ 简单介绍一下使用方法:public class Exampl
2016-08-14 19:24:46
4890
转载 java中的注解
注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁。 注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解: @Override,表示当前的方法定义将覆盖超类中的方法。 @Deprecated,使用了注解为它的元素编译器将发出警告,因为
2016-08-14 19:08:32
389
转载 HTTP协议之报文详解
学习WEB开发需要对HTTP协议熟悉,下面直接进入主题。一、什么是报文报文,是网络中交换和传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变。HTTP报文是由一行一行简单的字符串组成的。HTTP报文都是纯文本,不是二进制代码,所以人们可以很方便地对其进行读写。如果说HTTP是因特网的信使,那么HTTP报文就是它用来
2016-06-03 00:05:19
447
转载 字符串匹配算法--KMP算法
前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k;但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导论,32章 字符串匹配虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲。今天我在这里讲一讲我的一些理解,希望大家多多指教,如果有不清楚的或错误的请给
2016-05-28 11:55:23
320
原创 String,StringBuffer与StringBulider三者的区别
我们都只到String和StringBuffer的区别,即String是不可拓展的,即String如果要实现A字符串+B字符串的效果,则不能直接把B接在A后面,而必须新开一个C,然后把A+B放进C.而StringBuffer是可拓展的,如果A是StringBuffer要实现A+B的效果只要把B放进A后面就行了(append())。那么为什么他们有这样的区别呢,还是来看看源码就知道了。//Str
2016-05-27 23:28:21
1120
转载 Java动态绑定机制原理分析
在Java方法调用的过程中,JVM是如何知道调用的是哪个类的方法源代码? 这里面到底有什么内幕呢? 这篇文章我们就将揭露JVM方法调用的静态(static binding) 和动态绑定机制(auto binding) 。 ★ 静态绑定机制Java代码 //被调用的类 package hr.test; class Father{
2016-05-27 18:38:49
2018
转载 Binder源码分析之Java层
前面的几节中我们介绍了Native层Binder通讯的原理和用法,那么在Java层如何使用Binder通讯呢?其原理又与Native层的Binder有什么关系呢? 与Native层的ServiceManager类似,Android在Java层也有一个ServiceManager用于处理Java层Service的注册、申请。只不过,Java层的这个ServiceManager,其实
2016-05-26 12:13:18
653
原创 分配排序之--桶排序,基数排序
桶排序的思想:其实就是先分配在收集的这个一个过程。比如开一个数组,然后把待排序数列里比如1就放到数组位置1,3就放到数组位置3,然后把这个数组里按顺序输出,则这个数列就变成有序了。 基数排序,上面的桶排序是对单关键码进行排序,显然当排序的数大了以后,比如出现数字10000,不可能给他开个10000的数组,对内存资源浪费也十分严重,那么基数排序就是优化了这一问题,即他是对多关键码进行
2016-05-17 20:49:18
552
原创 选择排序之--简单选择排序,堆排序
简单选择排序的思想很简单:每次从无序区里选出一个最小的的数,然后把他放进有序区的末尾,如此往复,直到全部有序。 堆排序,堆排序是对简单选择排序的一种改进,显然简单选择排序,要经过大量的比较的出最小的数,而堆排序的着眼点就在于减少比较的次数,那么如何来实现减少比较次数呢,是的,很自然的想到二叉树,下面说一下堆排序的基本思想。 堆排序的基本思想:先说一下堆的概念:即一完全
2016-05-17 20:36:31
489
原创 交换排序之--冒泡排序,快速排序
冒泡排序是一种很经典的排序方式了,当然他也是最简单的一种交换式排序,冒泡排序的思想很简单,从前面开始,每每两个数相比,如果前面的大于后面的则交换位置,知道最后一个数,这样一轮排序下来,最大的数就跑到了最后面,如此往复,知道全部有序。 当然上面是最简单的冒泡排序,他显然有一个很大的缺点,就是做了很多的重复劳动,当我们开始排序的时候,实际上整个数列就可以分成有序区和无序区,而根据冒泡排
2016-05-17 18:57:22
815
原创 插入排序之--直接插入排序,希尔排序
直接插入排序是插入排序里最简单的一种,他的排序方式十分直接,就是从拿无序区的第一个数开始与有序区的最后一个数往前开始比,如果比他大,则直接插入在他后面,如果比他小,则继续往前比,直到找到合适的地方插入。如此往复,最终实现全部有序。 虽然直接插入排序是一种比较简单直接的排序,但是他仍然有可以优化的地方,我们可以把数组的第一个位置让出,固定用来放待排序的那个数,这样r[0]的位置相当于
2016-05-17 14:05:45
359
原创 单例模式分析
单例模式在我们项目中经常被用到,可能也是设计模式中比较简单的一种,实现单例的方式有好几种,有各自的优缺点,对于一些整个项目中只需要一个的实例,特别是这个对象内部占的资源还很大的时候,单例模式无疑是十分节省资源的,是一种优秀的实现。 1.饿汉单例模式 //饿汉式单例模式 public class EHSingleton { //直接创建单例
2016-05-16 15:17:11
412
原创 面向对象编程的六大原则
要让自己写的代码有质量,特别是对于面向对象编程的话,代码以及框架的是否合理直接决定了你的程序是否可以良好的扩展和壮大,这在软件工程中也多少学过一点,简单来说就是要做到低耦合高内聚,经过编程人员多年的总结,良好的框架设计或者说编码风格应当做到以下六个原则,当然这六个原则要在实际应用中去体会才能更好的理解。 1.单一职责原则 这是优化代码的第一步,当我们设计程序时,某一功
2016-05-15 01:17:10
4154
原创 利用wait()和notify()实现生产者与消费者问题
生产者与消费者问题是并发编程里面的经典问题,下面用wait()和notify()来实现消费者线程和生产者线程的并发执行。 说之前先讲几个概念: wait()与sleep()的区别: 1.首先sleep()是Thread()类的方法,而wait()是Object类的方法,包括notify(),notifyAll()都是Object类的方法 2.
2016-05-13 11:42:53
8471
2
转载 Reactor反应器模式
概述Java NIO非堵塞技术实际是采取反应器模式,或者说是观察者(observer)模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。同步和异步区别:有无通知(是否轮询)堵塞和非堵塞区别:操作结果是否等待(是否马上有返回值),只是设计方式的不同NIO 有一个主要的类Selector,这个类似
2016-05-09 19:20:17
457
转载 Java NIO使用及原理之--选择器Seclector
转载自:李会军•宁静致远在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O。通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据。同样,写入调用将会阻塞直至数据能够写入。传统的Server/Client模式会基于TPR(Thread per Request),服务器会为每个客户端请求建立一个线程,由该线程单独负
2016-05-09 19:06:02
1896
转载 Java NIO使用及原理之--缓冲器buffer(2)
转载自:李会军•宁静致远在上一篇文章中介绍了缓冲区内部对于状态变化的跟踪机制,而对于NIO中缓冲区来说,还有很多的内容值的学习,如缓冲区的分片与数据共享,只读缓冲区等。在本文中我们来看一下缓冲区一些更细节的内容。缓冲区的分配在前面的几个例子中,我们已经看过了,在创建一个缓冲区对象时,会调用静态方法allocate()来指定缓冲区的容量,其实调用 allocate()
2016-05-09 18:53:24
1186
转载 Java NIO使用及原理之--缓冲器buffer(1)
转载自:李会军•宁静致远在第一篇中,我们介绍了NIO中的两个核心对象:缓冲区和通道,在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如果我们使用get()方法从缓冲区获取数据或者使用put()方法把数据写入缓冲区,都会引起缓冲区状态的变化。本文为NIO使用及原理分析的第二篇,将会分析NIO中的
2016-05-09 18:50:36
2004
转载 Java NIO使用及原理之--总概述
转载自:李会军•宁静致远最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下,顺便写点东西,就当是自己学习 Java NIO的笔记了。本文为NIO使用及原理分析的第一篇,将会介绍NIO中几个重要的概念。在Java1.4之前的
2016-05-09 18:48:26
487
原创 java中一些容器底层的数据结构解析
先来看一个java里一些主要容器的继承图: 然后分别解析一下上面几种容器底层的数据结构以及一些实现:1.ArrayList(非线程安全的)底层的数据结构其实就是数组,但是它比数组优秀的地方在于他是动态的,即不必像数组那样固定大小,那么他是如何实现这种数据结构是数组,但是给我们看起来确实不固定大小的呢?ArrayList 是通过将底层 Object 数组复制的
2016-05-08 23:52:34
8971
转载 Java并发编程之volatile关键字解析
volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。 volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们
2016-05-08 17:34:43
414
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人