Android开发中需要注意哪些坑

作为一个有两、三年Android应用开发经验的码农,自然会遇到很多坑,下面是我能够想起的一些坑(实践证明不记笔记可不是个好习惯),后面有想到其它坑会陆续补上。

1.在Android library中不能使用switch-case语句访问资源ID:在Android library中不能使用switch-case语句访问资源ID的原因分析及解决方案

2.不能在Activity没有完全显示时显示PopupWindow和Dialog:popupwindow - Problems creating a Popup Window in Android Activity

3.在多进程之间不要用SharedPreferences共享数据,虽然可以(MODE_MULTI_PROCESS),但极不稳定:android - MODE_MULTI_PROCESS for SharedPreferences isn‘t working

4.有些时候不能使用Application的Context,不然会报错(比如启动Activity,显示Dialog等):

5.同一个应用的JNI代码,不要轻易换NDK编译的版本,否则会有很多问题(主要是一些方法实现不一样,并且高版本对代码的检测更严格),比如r8没有问题,但到r9就有问题了,这是个大坑;

6.Android的JNI代码中,有返回类型的函数没有返回值编译的时候也不会报错;

7.当前Activity的onPause方法执行结束后才会执行下一个Activity的onCreate方法,所以在onPause方法中不适合做耗时较长的工作,这会影响到页面之间的跳转效率;

8.谨慎使用Android的透明主题,透明主题会导致很多问题,比如:如果新的Activity采用了透明主题,那么当前Activity的onStop方法不会被调用;在设置为透明主题的Activity界面按Home键时,可能会导致刷屏不干净的问题;进入主题为透明主题的界面会有明显的延时感;

9.不要在非UI线程中初始化ViewStub,否则会返回null;

10.公共接口一定要考虑到代码重入的情况,能设计为单例就尽量用单例;

11.不要通过Bundle传递大块的数据,否则会报TransactionTooLargeException异常:Java - Issue: Passing large data to second Activity

12.尽量不要通过Application缓存数据,这不稳定:不要在Android的Application对象中缓存数据!

13.尽量不要使用AnimationDrawable,它在初始化的时候就将所有图片加载到内存中,特别占内存,并且还不能释放,释放之后下次进入再次加载时会报错;

14.9图不能通过tinypng压缩,不然会有问题;

15.genymotion模拟器快是因为它是基于x86架构的,如果你的应用中用到了so,但没有x86架构的so,只能放弃使用它;Android Studio的模拟器也一样;

16.Eclipse的Android开发环境配置好后不要轻易升级ADT和build tools,不然会浪费你很多时间,还有就是一个workspace中的工程不要太多,不然每次启动都会很慢;

17.Android studio每个版本、gradle每个版本差别都比较大(我是这样认为的),对于jni代码的编译建议在Eclipse中进行,如果在Android studio中开发jni会浪费很多时间,主要是编译脚本的配置比较麻烦;

18.Eclipse中的Lint太不靠谱,特别是主工程中依赖library的时候,很多提示都是有问题的,建议使用Android Studio的工程清理工具,特别推荐;

19.不同API版本的AsyncTask实现不一样,有的是可以同时执行多个任务,有的API中只能同时执行一个线程,所以在程序中同时执行多个AsyncTask时有可能遇到一个AsyncTask的excute方法后很久都没有执行。调用AsyncTask的excute方法不能立即执行程序的原因分析及改善方案

20.同一个应用,相同的图片分别放在drawable-xxhdpi、drawable-xhdpi、drawable-hdpi、drawable-mdpi、drawable-ldpi中,在同一设备中占用的内存会大不一样(设备的dpi是固定的,图片放在不同的dpi文件夹下,在设备上显示时需要将图片转换成和当前屏幕一样dpi后在设备中显示,所以即使该图片在不同dpi文件夹下大小一样,但放在内存中的大小却不是一样的,并不一定是长*宽*4),做应用的内存优化之前可以先看一看你的工程是如何做屏幕适配的,是否有优化的空间。强烈推荐这个屏幕适配视频教程,花两个半小时就能看完:Android-屏幕适配全攻略

21.谨慎对待数据库升级(比如需要在原数据库中增加字段),避免数据丢失或者操作数据库异常的情况,数据库升级方法可以查阅《第一行代码》P263;

22.多个程序共用一套代码(一套代码,在桌面上多个图标)时需要处理好不同入口进入时的堆栈问题;

23.使用Adapter的时候,如果你使用了ViewHolder做缓存,在getView的方法中无论这项的每个视图是否需要设置属性(比如TextView设置的属性2可能为null,item的某一个按钮的背景为透明、某一项的颜色为透明等),都需要为每一项的所有视图设置属性(textview的属性为空也需要设置setText(""),背景透明也需要设置),否则在滑动的过程中会出现内容的显示错乱。

24.谨慎使用Android的多进程,多进程虽然能够降低主进程的内存压力,但会遇到如下问题:(1)不能实现完全退出所有Activity的功能(如果有同行在应用内采用多进程成功实现过完全退出程序欢迎沟通交流);(2)首次进入新启动进程的页面时会有延时的现象(有可能黑屏、白屏几秒,是白屏还是黑屏和新Activity的主题有关);(3)应用内多进程时,新启动一个进程都会重新跑一次Application的onCreate方法,不上重新创建一个Application,但会重新跑Application的onCreate,这样就不能在Application中缓存数据作为内存共享的途径了;(4)多进程间通过SharedPreferences共享数据时不稳定,具体可以查阅《Android开发艺术探索》。

25.使用Toast时,建议定义一个全局的Toast对象,这样可以避免连续显示Toast时不能取消上一次Toast消息的情况(如果你有连续弹出Toast的情况,避免使用Toast.makeText);

26.View的面积越大绘制的时间就越长,透明通道对View的绘制速度影响很大;

27.不要通过Msg传递大的对象,会导致内存问题。

时间: 2024-10-27 07:57:57

Android开发中需要注意哪些坑的相关文章

Android 开发中踩过的坑之十一: 团队协作的坑

工作中,android的坑很多,一部分是android源码自身的逻辑陷阱, 但跟多的是自己和同事们由于种种原因埋下的坑. 提高面向对象的能力,并恰当的实现在代码中,能够极大的减少坑人和被坑几率. 面向对象的最大特征是复用, 复用的目的是减少工作量,减少错误几率,提高工作效率. 总结几个自己的体会,以自勉: 1 在编码前明确代码的模块框架, 定义最简单的接口. 有人也许说, 书生造反,十年不成, 在工期紧张或者其他类似敏捷编程的大背景下, 先干起来才是硬道理. 事实上, 工期紧张也许正是因为之前的

Android 开发中踩过的坑之六:几个关于View的tips

这几个点, 不算是坑, 但是也确实浪费了我一些时间 1.ScrollView的高设置成"wrap_content"会缩的很小,  ScrollView内只允许嵌套一个View, 并且不要将他的高度设置为"wrap_content", 否则它会缩小到很短的样子. ListView也是一样. 2.ListView中的Item如果有不同的样式,最好使用getItemViewType()来区别 事实上, 在ListView的Item完全可以用一种View布局来控制Visia

Android 开发中踩过的坑之八:多进程问题

这是个需要细心处理的坑. 1 内存: 在manifest中可以对各个组件声明其所在的进程: android:process=":name" 然后对应的Acitivity, Receiver, Service就会运行在相应的进程中. 但是有些类会在所有进程中运行, 比如一些Utils工具类, 比如Application类. 当遇到多个进程并行的时候, 厘清进程所对应的代码, 避免在进程A里跑了进程B的代码. 比如有一个工具类Utils_procA. 只需要在进程A中工作, 那对于进程B来

Android 开发中踩过的坑之十: 谨慎处理动画的开始和结束

Android提供多种动画机制, 从面相对象的方式到直接实现底层onDraw的方式, 给予了足够的控件实现希望的效果, 无论时使用哪种方式实现动画, 都要谨慎的处理动画的两个状态, 开始和结束 需要关注的问题有: 1 动画开始的时候是否需要重新初始化内存? 对于需要重复展示的动画, 应当避免每次都new新的内存, 否则在动画展示过程, 内存会不断增加, 而gc合适回收, 是不确定的. 也许当gc时, 你已经在OOM的边缘了. 2 动画开始时是否是从某个中间状态开始的? 动画从某个中间状态开始,

Android 开发中踩过的坑之七:尽量避免使用Acitivity当做Context

这坑容易埋, 却不容易发现. 比如启动一个页面, 需要用到一个单例的工具类Utils, 初始化Utils需要一个Context参数, 直接传入Activity.this. 然后这个单例的Utils就会一直持有Activity.this, 导致整个Acitivity不能被GC. 而如果代码中大量的使用Utils, 又不能确认到底谁最先初始化了Utils, 使得内存泄露成了灵异事件难以发现. 所以, 正确的使用方式是: activity.this.getApplicationContext(); g

Android 开发中踩过的坑之二: 16ms的UI线程时间才不会卡顿

AndroidUI卡顿, 是总会遇到的问题, 这个坑经常遇到, 通常在优化时才会重点关注. 通常在Adapter.getView()方法中比较突出. 人眼的原因, 1秒24帧的动画才能感到顺畅. 所以每帧的时间大概有41ms多一点点(1000ms/24). 但是但是, 注意了, 这41ms不是全都留给你java代码, 而是所有java native 屏幕等等的, 最后留给我们用java级别发挥的时间, 只有16~17ms了. 所以,当你优化视觉效果时, 留意UI线程的时间, 超过16ms, 就需

Android 开发中踩过的坑之九: 发布一个aar的注意事项

现在Android支持aar格式发布一个模块, 提供给其他人使用. aar其实是jar和一些资源文件的zip包. 解决了过去jar包不能分享资源的局限. 1 要尽量避免定义内部接口, 这其实是一个编程习惯, 接口interface最好是独立定义, 避免定义在类的内部. 因为当你发布aar时, 内部的接口在混淆后会独立成一个外部的接口Outer$InnerInterface. 然后麻烦来了, 别人在实现这个类的时候必须也写成XXX implement Outer$InnerInterface{}的

Android 开发中踩过的坑之四:低版本使用AsyncTask

这个坑比较隐晦, 一般不容易出现. 有可能在使用AsyncTask时, 明明就是在postResult()方法里设置UI, 却被告知不能在非UI线程设置UI的异常. 这实际上应用App启动时的一个bug. AsyncTask是在初始化的时候, 自己取当前的线程获取Looper. 但是问题来了, 当前线程可能并不是UI线程, 所以就导致了postResult()等原本应该在UI线程工作方法, 实际上在非UI线程. 谷歌在4.1以后版本里解决这个bug, 就是在应用启动时, 在UI线程里先调用了一次

Android 开发中踩过的坑之十一: 避免使用Shader做动画

进来优化内存, 发现5.0的系统上, Shader有个不算bug的小问题, Shader在绘制时, 会copy自身, 如果使用shader做动画, 就会不断的copy自身, 不断的增加使用内存. 大概2k/s的速度上涨 sdk放出的源码中有一个@hide的方法copy(), 怀疑就是它导致内存不断增长, 但是查不到调用. 解决方法也简单, gc一下, 或者避免使用shader来做动画.