`
Teok
  • 浏览: 147809 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android开发中的一些经验总结

阅读更多

计划用这篇文章把目前我在Android领域的一些看到的、用到的、想到的经验和技巧总结一下。

1. WeakReference和AsyncTask的美妙结合

为了避免开发者在UI线程上做耗时操作,Android提供了不少异步API,其中之一就是AsyncTask。而对于某些频繁操作数据库的应用(例如,Phonebook)而言,需要一种异步的并且低耗资源的(低耗是两个方面的事情,要么是你占有的多点,但是能快速释放;要么是你本身就占有的少。这两种都可以保证其它应用有资源可用)组件。所以,那就来个WeakAsyncTask吧,唔,美妙的产物,既保证占有资源的快速释放,又保证操作是异步进行。

那为什么不是soft reference呢?

这个,来看看weak和soft两者的区别:

 

    * A SoftReference should be cleared and enqueued as late as possible, that is, in case the VM is in danger of running out of memory.

    * A WeakReference may be cleared and enqueued as soon as is known to be weakly-referenced.

不用问嘛,哪里能等到vm内存快光光的时候再去释放早已不用的资源啊,那个时候可能手机的UI看起来就卡卡的了。。

下面来看段代码:

 

public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget> extends
        AsyncTask<Params, Progress, Result> {
    protected WeakReference<WeakTarget> mTarget;

    public WeakAsyncTask(WeakTarget target) {
        mTarget = new WeakReference<WeakTarget>(target);
    }

    /** {@inheritDoc} */
    @Override
    protected final void onPreExecute() {
        final WeakTarget target = mTarget.get();
        if (target != null) {
            this.onPreExecute(target);
        }
    }

    /** {@inheritDoc} */
    @Override
    protected final Result doInBackground(Params... params) {
        final WeakTarget target = mTarget.get();
        if (target != null) {
            return this.doInBackground(target, params);
        } else {
            return null;
        }
    }

    /** {@inheritDoc} */
    @Override
    protected final void onPostExecute(Result result) {
        final WeakTarget target = mTarget.get();
        if (target != null) {
            this.onPostExecute(target, result);
        }
    }

    protected void onPreExecute(WeakTarget target) {
        // No default action
    }

    protected abstract Result doInBackground(WeakTarget target, Params... params);

    protected void onPostExecute(WeakTarget target, Result result) {
        // No default action
    }
}

 而通常,weaktarget经常会以activity为参数,这样的话,就更为贴切的。因为context的错误引用而导致的内存溢出问题也是挺常见的。

 


2. Sqlite机制导致的饿死(ANR)
我们知道,Android的数据库是用的sqlite,而且sqlite是全局的,也就是说,对于一个Android系统实例而言,所有的程序将会共用一个sqlite database。这里就会有一个有意思的事情发生:当某个应用A正在进行某个长耗时的数据库操作时,另外一些应用B在此期间也需要进行数据库操作,但是数据库被A独占,B只能等,等着等着,超过5秒了,好吧,B被ANR了。

事实上,这种情况不总出现。前提是A的操作属于独占式的操作,B在主线程上进行数据库操作。解决方法自然也分为两种,一种是A换用批量操作API:ContentProviderOperation,用ContentProviderOperation.Builder.withYieldAllowed (true)来允许当前的数据库操作可以被挂机;另外一种是B不要在主线程里进行数据库操作。

说道这里,我更加明白了google I/O视频上那个大哥为啥说"never, never, never do slow things on UI thread"了,因为没准哪天,你就被别人ANR了。。

  

3.如何解决ANR

一个朋友去一家智能手机公司面试开发时被问到如何解决ANR的问题。正好,公司的arc前两天对解决ANR进行一些经验分享。(总结的不一定全)

1.ANR有哪几种?

从ActivityManagerService的实现可以看到,ANR有四种,分别对应Android的四个fundermetals。这个也不难理解:所有fundermetal都会在main thread上运行,如果超过了响应的间隔,那么就会ANR。另外JNI调用native函数时也会发生无响应,不过我觉得应该不算单独的一种,它只是未响应发生在了native里,而不是vm里。

2.ANR是什么?

从ActivityManagerService可以看到,作为一个manager类,要去检测所管理的对象是否处于可相应状态,一个不错的方式就是给那个对象发消息,并等待回调。事实上,就是这么做的。每隔一段时间,manager会发消息给所有fundamental,这个消息格式固定,同时带一个delay time,譬如说activity的delay time就是5000ms,当消息发出之后,5000ms之内没有收到相应,那么manager就要把那个activity ANR掉。对于broadcast receiver、provider和service也是同样的,只是delay time不一样。

以Activity为例,几个负责Activity生命周期的回调方法(以on开头的那几个),被调用后,5000ms内没有返回,那么就ANR鸟。另外还有key dispatch ANR,也就是说,当用户点击了进行了某些操作产生key event了,那么应用就必须在规定时间处理key event,如果超时,会立刻ANR。

3.ANR的导致原因

我叙述一下google I/O 2010上一个presentation上说的:就是性能问题。我们知道,一般情况下,Android系统的瓶颈经常在I/O操作,无论是本地还是网络,经常会导致程序看起来不那么顺畅,如果达到某个时间没有响应,那么就ANR鸟。我猜测,

4.如何避免ANR

"Never never never do slow things on main thread".我引用了那个presentation的原话。

5.如何解决ANR的问题

上面介绍了ANR的一些基本知识,但是在现实问题中,ANR的问题经常会比较难解决。而且每一种ANR在logcat的信息中都会有不同的。如果要了解不同ANR的特点,就需要些多个实例来观察log信息。这里需要关注的几个信息是,线程、内存、CPU、异常堆栈等信息。google貌似提供了工具来dump发生ANR时的系统及APP信息。

分享到:
评论

相关推荐

    android开发经验分享

    android开发经验总结分享,对android 开发的工程人员有帮助

    android framework 经验总结

    android framework开发经验总结

    android开发总结,实战经验

    android开发总结,实战经验,新手入门

    阿里巴巴Android开发手册正式版1.0.1

    《阿里巴巴 Android 开发手册》是阿里巴巴集团各大 Android 开发团队的集体智慧结晶和经验总结,将淘宝、天猫、闲鱼、钉钉等 App 长期开发迭代和优化经验系统地整理成册,以指导 Android 开发者更加高效、高质量地...

    Android十年终极开发经验_助您不走弯路_快速晋级Android架构师

    ** 行业标准: 作者有数年Android开发经验. ** 专业: 数年Android问题debug经验,Android解读专业到位 ** 咨询: 承诺文档解读有疑问,可以免费每天3个问题的解答 ** 退款: 作者承诺如果对于文档不满意,可线下联系...

    高通平台android开发总结

    绝对超值的文档,详细讲解高通平台开发相关经验(boot, kernel, android)等。

    android开发资料大全

    新版Android开发教程及笔记-完整版 《Android中文教程》中文版 《android基础教程合集》 Android实例教程 会员贡献索引贴 实用Android开发工具和资源精选 APK权限大全 - Android必懂知识 最无私的Android资料...

    新版Android开发教程笔记

    新版Android开发教程笔记,一共为十三章,为PDF格式文档,总结了android编程过程中遇到的一些问题及解决办法,另外介绍了编程技巧。非常适合初学者,对于熟练的编程人员也可作参考。内容非常详实,并有详细的目录!

    打造高质量Android应用:Android开发必知的50个诀窍

    资源名称:打造高质量Android应用:Android开发必知的50个...作译者都是经验丰富的Android开发工程师,作者悉心总结Android应用开发中会遇到的50个经典问题资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    Android入门到精通知识总结.pdf

    Android入门到精通知识总结,适合与Android知识的中初级学习者,个人Android开发实例及经验总结

    巴里巴巴Android开发手册(正式版)

    阿里巴巴Android开发手册,是阿里Android开发团队集体的智慧结晶和经验总结。

    14本安卓android开发教程书籍源代码.rar

    14本安卓android开发教程书籍源代码让您从安卓开发新手到高手,快速具备独立开发经验,最全api教程大合集 安卓AndroidAPI教程 安卓android编译总结 安卓android开发从零开始代码若水 二维码生成图片 安卓中国象棋源码 ...

    Android开发实战体验

    资源名称:Android开发实战体验内容简介:《移动开发技术丛书:Android开发实战体验》是DevDiv移动开发社区版主、资深会员在该平台实际开发经验的总结,通过大量原创示例全面介绍了Android应用开发的方法和技巧。...

    android ndk 开发

    android ndk 开发总结,总结android ndk开发过程中的经验!

    Android开发必知的50个诀窍 pdf

    作译者都是经验丰富的Android开发工程师,作者悉心总结Android应用开发中会遇到的50个经典问题,这些问题涉及布局、动画、视图、工具、列表、适配器、实用库、与其他编程语言的交互、数据库、构建工具、代码复用、...

    阿里巴巴 Android 开发手册正式版

    结晶和经验总结,将淘宝、天猫、闲鱼、钉钉等 App 长期开发迭代和优化经验系统地整 理成册,以指导 Android 开发者更加高效、高质量地进行 App 开发,呈现给用户体验好、 性能优、稳定性佳、安全性高的产品。

    阿里巴巴Android开发手册.pdf

    《阿里巴巴 Android 开发手册》是阿里巴巴集团各大 Android 开发团队的集体智慧 结晶和经验总结,将淘宝、天猫、闲鱼、钉钉等 App 长期开发迭代和优化经验系统地整 理成册,以指导 Android 开发者更加高效、高质量地...

Global site tag (gtag.js) - Google Analytics