zhengxiaoyong

Android Engineer.


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于
zhengxiaoyong

Android运行时Crash自动恢复框架-Recovery

发表于 2016-09-05 | 分类于 开源框架 | | 阅读次数

简介

App Crash的恢复,这个想法很早之前就有,目前有些时间就实现了一把,主要是对App运行时发生Crash后,对Activity的堆栈和数据进行恢复,或者重启应用,或者重启并清空缓存,避免因本地的数据类型或格式错误而导致App在读取时一直Crash,Debug模式还包括Crash信息的显示和保存,便于在开发、测试时查看相应CrashInfo

Crash的处理

对于应用的Crash,一般的做法我们往往都是实现个自定义UncaughtExceptionHandler,而这个自定义的CustomUncaughtHandler我们一般都用于捕捉Crash信息进行上报和监控是否发生Crash,还有一个作用就是可以屏蔽系统默认的Crash对话框,也就是拦截Crash后不把系统默认的UncaughtHandler设置进去,而是直接进行KillProcess,这个过程就是屏蔽了系统的默认Crash处理流程,原因是系统的处理其中在AMS的crashApplication()中会执行这么一段代码:

1
2
3
4
5
6
7
Message msg = Message.obtain();
msg.what = SHOW_ERROR_MSG;
HashMap data = new HashMap();
data.put("result", result);
data.put("app", r);
msg.obj = data;
mUiHandler.sendMessage(msg);

发送一个显示Dialog的消息,之后便创建一个AppErrorDialog进行显示。

阅读全文 »
zhengxiaoyong

Android端应用秒开优化体验

发表于 2016-07-18 | 分类于 性能优化 | | 阅读次数

前言

最近部门内抛出了一个问题,应用启动很慢、卡图标?主要表现在中低端机型中。究其这个问题,由于对性能优化比较感兴趣,借了个低端机和一个中端机来一看究竟,对同一应用分别测了下它在中低端机的启动时间,下面为启动耗时情况:

启动了三次,基本都在4s左右。

阅读全文 »
zhengxiaoyong

UrlRouter路由框架的设计

发表于 2016-04-24 | 分类于 技术沉淀 | | 阅读次数

UrlRouter的设计

目的

1、可取代使用startActivity、startActivityForResult跳转的情景,便于协同开发
2、通过一串url可任意跳转到指定界面,使用应尽可能简单
3、支持各种类型参数传递、界面转场动画
4、可获取起跳界面的路径和当前界面路径,以便支持后期埋点等需求
5、支持从H5到Native,Native到H5,这是Hybrid开发模式中常用到的需求
6、对于push、浏览器外链跳转等可方便配置化,通过一个url来跳转指定界面

阅读全文 »
zhengxiaoyong

Native与H5交互的那些事

发表于 2016-04-20 | 分类于 技术沉淀 | | 阅读次数

前言

Hybrid开发模式目前几乎每家公司都有涉及和使用,这种开发模式兼具良好的Native用户交互体验的优势与WebApp跨平台的优势,而这种模式,在Android中必然需要WebView作为载体来展示H5内容和进行交互,而WebView的各种安全性、兼容性的问题,我想大多数人与它友谊的小床已经翻了,特别是4.2版本之前的addjavascriptInterface接口引起的漏洞,可能导致恶意网页通过Js方法遍历刚刚通过addjavascriptInterface注入进来的类的所有方法从中获取到getClass方法,然后通过反射获取到Runtime对象,进而调用Runtime对象的exec方法执行一些操作,恶意的Js代码如下:

1
2
3
4
5
6
7
8
9
function execute(cmdArgs) {
for (var obj in window) {
if ("getClass" in window[obj]) {
alert(obj);
return window[obj].getClass().forName("java.lang.Runtime")
.getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
}
}
}

为了避免这个漏洞,即需要限制Js代码能够调用到的Native方法,官方于是在从4.2开始的版本可以通过为可以被Js调用的方法添加@JavascriptInterface注解来解决,而之前的版本虽然不能通过这种方法解决,但是可以使用Js的prompt方法进行解决,只不过需要和前端协商好一套公共的协议,除此之外,为了避免WebView加载任意url,也需要对url进行白名单检测,由于Android碎片化太严重,WebView也存在兼容性问题,WebView的内核也在4.4版本进行了改变,由webkit改为chromium,此外WebView还有一个非常明显的问题,就是内存泄露,根本原因就是Activity与WebView关联后,WebView内部的一些操作的执行在新线程中,这些时间无法确定,而可能导致WebView一直持有Activity的引用,不能回收。下面就谈谈怎样正确安全的让Native与H5交互

阅读全文 »
zhengxiaoyong

关于生产者-消费者-订阅者模式的那些事

发表于 2016-01-27 | 分类于 技术沉淀 | | 阅读次数

生产者/消费者模式

简介

用来干嘛的?

生产者/消费者模式的产生主要目的就是为了解决非同步的生产与消费之间的问题。

什么是非同步呢?
比如我刚刚生产了某个产品,而此时你正在打游戏,没空来取,要打完游戏来取,这就导致了我生产产品和你取产品是两个非同步的动作,你不知道我什么时候生产完产品,而我也不知道你什么时候来取。

而生产者/消费者模式就是解决这个非同步问题的,因为肯定不可能我生产完一个就给你打个电话叫你来取,然后等你取完我再生产下一个,这是多么低效的一种做法。所以这个模式运用而生,这个模式在生活中也有很好的体现,如:快递员派信这个例子,我就是生产者,快递员就是消费者,而生产者与消费者之间是通过什么来解决这种非同步的问题呢?就是一个存储中介,作为快递员派信这个例子中,信箱就是这个存储中介,每次我只要把写完的信扔入信箱,而快递员隔三差五的就会来取一次信,这两个动作是完全异步的,我把信扔入信箱后就不需要管什么了,之后肯定有快递员来取。

阅读全文 »
zhengxiaoyong

Android性能优化之Splash页应该这样设计

发表于 2016-01-17 | 分类于 性能优化 | | 阅读次数

目前SplashActivity的设计

目前市场上的应用在启动时基本上都会先启动一个SplashActivity,作为一个欢迎界面,为什么这样设计呢?
个人总结有三个优点:

可以给用户更好的体验

比如:可以由后台动态的改变欢迎的图片,或者显欢迎xxx回来,新浪微博的就是这种交互。

可以缩减App的启动时间

由上一篇博文中知道app启动的耗时主要是在Application初始化中和MainActivity的界面绘制前,由于MainActivity的业务和布局复杂度肯定比只显示一张图片的界面高,所以,加入一个显示一张图片的Splash页可以优化应用的启动。

可以在应用启动时做更多的事

一般来说SplashActivity一般会设计成停留2到4s不等,或者根据数据的加载程度来动态的设置Splash界面的停留时间,既然停留那么久,那么当然可以在这个界面背后做一些事以备MainActivity的快速显示,比如:数据的预加载、sp的初始化、网络请求等。

当然你可能有些疑问,那这样初始化放在Application中也可以啊?也用异步操作数据也是一样啊?

答案是不一样!正如上篇所说的,Application初始化时并不会加载界面,而是在它创建完和初始化完成后,开始创建Activity时才开始绘制Theme中的background和绘制布局,所以用一个轻量的Splash页给它设置一张背景欢迎图,这样就立马能显示界面了,而在这个界面中还可以做其它的初始化操作,这样在视觉上即达到了app的快速启动,又添加了体验和做数据的初始化。

相反如果过多的放在Application中,则在点击app图标启动时会感觉延迟,必须要把Application中的东西都做完才进入Activity的配置和绘制中。

阅读全文 »
zhengxiaoyong

Android性能优化之加快应用启动速度

发表于 2016-01-14 | 分类于 性能优化 | | 阅读次数

应用的启动

启动方式

通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动

1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。

2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

阅读全文 »
zhengxiaoyong

Fresco图片框架内部实现原理探索

发表于 2016-01-04 | 分类于 技术沉淀 | | 阅读次数

流行的网络框架

目前流行的网络图片框架:
Picasso、Universal Image Loader、Volley的(ImageLoader、NetworkImageView)、Glide和Fresco

简明的介绍下(具体细节和功能可看源码和wiki):
其中Picasso和Universal Image Loader相比其它的算是最轻量级的图片框架了,它们拥有较少的方法数,Universal Image Loader是这五个框架中定制性最强的,它内部实现还是按网络框架的套路走:HttpUrlConnection+线程池+Handler,支持渐显效果。
而Picasso只有一些图片加载框架应有的基本功能,所以因此它是最轻量的,在需求只要基本的图片加载与双缓存功能下,可以选Picasso作为项目的基础库,Picasso它内部默认是使用OkHttpClient作为加载网络图片的下载器,毕竟不用自家用谁的,在OkHttpClient没有的情况下则使用HttpUrlConnection,同上面一样,下载器+线程池+Handler,不过它内部的线程池比较有意思,线程池的线程数量是根据当前的网络环境来动态改变的,wifi网络下为4,4G为3,3G为2,2G为1,其它情况下默认为3,支持渐显效果。
Volley的没什么可说的,基本功能都有,网络框架的附赠功能。

Glide的话,Google官方推荐,支持Gif、图片缩略图、本地视频解码、请求和动画生命周期的自动管理、渐显动画、支持OkHttp和Volley等等,默认是使用HttpUrlConnection加载图片的,源码灰常多,200多个类,不想看

Fresco我认为是这几个框架中性能最佳的一个框架,着重介绍,它内部用了大量的建造者模式、单例模式、静态工厂模式、生产/消费者模式。内部实现比较复杂,就拿图片加载来说,是通过在异步线程中回调图片的输入流,然后通过一系列读取、写入、转化成EncodedImage,然后再Decode成Bitmap,通过Handler转给UI线程显示,通过IO操作存储在硬盘缓存目录下。

阅读全文 »
zhengxiaoyong

Android性能优化之被忽视的优化点

发表于 2015-11-25 | 分类于 性能优化 | | 阅读次数

对于性能优化这个知识点来说,实在是太广了,博主本人也一直非常关注这方面的学习,而对于性能优化来说它包括了非常非常非常多方面,比如:I/O的优化、网络操作的优化、内存的优化、数据结构的优化、代码层次的优化、UI渲染优化、CPU资源使用率的优化、异常处理的优化等等等等。。。

本篇文章就博主本人的理解来讲述一些在Android开发中可以优化的地方

ArrayList和Vector

ArrayList和Vector都是内部以数组实现的List,它们两唯一的区别就是对多线程的支持,ArrayList是线程不安全的,而Vector内部对大多数方法都做了同步,是线程安全的,既然是线程安全的,所以性能方面肯定不如ArrayList了(当然想法肯定是对的),不过这需要看哪方面了,ArrayList在add、get、remove等操作效率肯定是高于Vector的,而在内存方面,Vector却比ArrayList表现的更好,这归根都是ArrayList的扩容策略导致的,稍后分析

阅读全文 »
zhengxiaoyong

Android性能优化之常见的内存泄露

发表于 2015-11-23 | 分类于 性能优化 | | 阅读次数

前言

对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我们可以借助LeakCanary、MAT等工具来检测应用程序是否存在内存泄漏,MAT是一款强大的内存分析工具,功能繁多而复杂,而LeakCanary则是由Square开源的一款轻量第三方内存泄漏检测工具,当它检测到程序中有内存泄漏的产生时,它将以最直观的方式告诉我们该内存泄漏是由谁产生的和该内存泄漏导致谁泄漏了而不能回收,供我们复查。

最近腾讯bugly也推出了三篇关于Android内存泄漏调优的文章:
1、内存泄露从入门到精通三部曲之基础知识篇
2、内存泄露从入门到精通三部曲之排查方法篇
3、内存泄露从入门到精通三部曲之常见原因与用户实践

关于性能优化的文章,出自Realm.io:
10 条提升 Android 性能的建议

阅读全文 »
123
郑晓勇

郑晓勇

21 日志
5 分类
58 标签
RSS
Github
© 2016 - 2019 郑晓勇