Google Developing for Android 学习总结
避免在循环中使用内存
也可理解为在循环中尽可能少创建对象,自定义控件避免在ondraw里面频繁创建paint对象。
尽可能避免内存分配
对象缓存:
常量通过类级别或者静态来进行缓存。
对象池:
同一种类型的多种对象,考虑使用对象池而不是分配频繁的分配内存。
(不是很理解,还需深入学习)
使用ArrayList.
android集合类:
使用ArrayMap或者simpleArrayMap代替HashMap.
需要修改的方法:
尽可能少用对象类型而是用原始类型的数据,android提供的SparseintArray和SparseLongArray集合类内部使用原始类型而不是对象类型。
使用集合遍历而不使用Iterator进行循环处理,因为使用Iterator会导致Iterator对象的内存分配。如果非要使用,进行非空判断。
避免使用枚举,因为在proguard优化代码和进行代码混淆的时候,枚举会被优化为int值。
针对使用第三方库,如果可能,尽可能抽取里面对自己有用的代码而避免无用的第三方代码。
避免static变量持有Activity的引用,因为这样会导致内存泄漏。
使用ActivityManager.isLowRamDevice()来进行应用的运行时内存限制。
使用IntentService代替service。
对你的应用代码进行瘦身操作。
避免在Application进行初始化操作,代替方法:使用单利来对全局的,公共的数据或者方法进行操作。
避免负责的layout的view层级,可以通过组合控件来将复杂的view布局写成可重用的,层级少的控件,比如titlebar等。
UI Thread减少耗时的操作。建议使用线程池进行DB和Network操作。自定义控件的时候避免在ondraw和onlayout中进行耗时操作。
完事后关闭掉你的Broadcast.避免因为相应过多的intent来影响设备的性能和资源消耗。
网络:
避免过于频繁的网络请求。因为消耗手机的电量和资源。
网络操作放到子线程(一般是线程池)中进行操作。
还要对网络变化的操作进行必要的网络状态检查和判断。
对于网络较差的环境问题的考虑。
网络接口层级别的设计,包括合理的请求和json数据接口。
语言以及库:
使用android自己的库去代替java的库api,比如ArrayMap代替HashMap,sParseArray等。
序列化:我一般写成BaseBean类实现serialize来实现序列化。
文章指出了parcelable序列化的缺点:
将Parcels写入到硬盘中是不安全的
你可以实现自己的Parcelables,但是如果在unparceling(Parcel反序列化)时不能访问到相同到类,那么就会unparcel就失败(对于向framework传递Parcels也适用)。
一些对象被存入到Parcels而不是共享内存中的情况,比如文件描述器,也许是很好的性能优化,但是隐藏了该Parcel对象真实的内存耗费(直到该对象被unparceling反序列化后才会占用真实的内存)。
在android5.0后,PersitableBundle类,可实现Bundle子类的数据的序列化,但是不支持Parcelables。
使用Parcelables ,sqlite,sharedPreferences来避免过度的序列化。
避免JNI,bug难调,多平台编译等缺点。
硬盘存储:
使用Environment.getExternalStorageDirectory() 代替:/sdcard
使用Environment.getExternalStorageDirectory() 代替:/sdcard
Context.getDatabasePath(), Context.getFilesDir()代替:/data/data/myapp/databases
持久化相对路径而不是绝对路径,因为路径存在路径存在变化的问题。
临时文件使用Context.getCacheDir()缓存路径。
过于简单的需求尽可能使用sharepreferences来解决而不去使用sqlite去操作。
避免创建过多的db文件,这个在使用ormlite,greendao很少出现这种问题,但是如果按照比较标准的sqlite android写法,有可能在sqliteopenhelper的集成类的创建db的方法中创建多个db文件,因此需要注意。尽量实现多表one db.
架构层:
使用fragement实现部分代码功能,减少service的使用。
避免startservice和bindservice两种对service的操作同时出现在一个逻辑里面。
通过binder传递大对象。
broadcast分发事件,service处理生命周期长的事件。
将UI处理从后台service中抽出来。(比如音频,将播放和视图分开)
有用的接口:
将网络操作的线程池和本地出具存储的线程池分开。确保不相互影响。
对请求和相应数据进行必要的缓存,请求的数据的缓存是为了在网络环境较差的情况下,进行可能的重试操作,而相应的数据是在网络环境差的情况下,避免体验不好的网络数据加载,比如对网络图片的三级缓存和数据的缓存等(数据可以通过orm缓存在数据库,图片利用第三方的piscco和umloader进行图片的缓存,避免不比较的重复加载,减少用户流量的浪费)。
避免异步的耗时操作长期持有view的引用。
适当处理好getApplication和activity的context之间的不同的使用,因为比如dialog的使用,就不能传递getapplication进行界面的显示。
tools:
systrace
allocationTracker
Traceview
Hierarchyviewer
MAT
MemoryMonitor
on-device
srictMode
profile Gpu rendering
debugGpu overdraw
Animator duration scale
adb shell screenrecord /sdcard/myscreenrecord.mp4
Show hardware layer updates
然而我只用过MAT,traceview ,strctMode,其他没怎么用过
文章参考自:http://www.lightskystreet.com/,并加上了自己的部分理解。详细可点击链接,去看lightsky的详细描述。