Android 开发中,都有哪些坑需要注意

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 开发中,都有哪些坑需要注意相关的知识,希望对你有一定的参考价值。

  1、不要排斥新技术和新工具。 android Studio 1.0 之后的版本,基本已经稳定到可以支持正常的工作开发的程度了。单纯就书写效率而言,Android Studio 带来的好处绝对大于它和Gradle的学习成本。JetBrains的IDE,用过都说好。还有就是适当的提升targetSdkVer… 显示全部
  1、不要排斥新技术和新工具。
  Android Studio 1.0 之后的版本,基本已经稳定到可以支持正常的工作开发的程度了。单纯就书写效率而言,Android Studio 带来的好处绝对大于它和Gradle的学习成本。JetBrains的IDE,用过都说好。
  还有就是适当的提升targetSdkVersion到新版本。

  2、代码设计方面的问题,大部分都能在Android系统源码里找到解决方案。
  当自己想设计一个新模块,或者实现一个新ui组件的时候,应该采用哪些设计模式、应该以哪种形式给外界提供接口之类的问题,大部分都可以参考Android系统的源码,找到实现方式。Google为安卓程序员提供了一座现成的宝库。

  3、理解Android和Java内存管理方式,至少要理解垃圾回收和Java的引用。
  就好比学OC就要先理解黄金法则一样,而java的内存管理,其实比OC要好理解多了。
  这可能会帮助大大减少程序异步操作产生的空指针崩溃。也会帮助理解为什么滥用单例模式会导致内存的臃肿。还会帮助养成不用“+”去连接超大字符串的好习惯。

  4、ContentProvider并不是只有在跨进程共享数据的才有用,把数据库表映射到一个独立的uri是Google鼓励的实现方式。
  从设计上讲,用uri(统一资源标识符)去描述数据,肯定比sql语句要理想。
  从效果上讲,用CursorLoader读取数据是让ios程序员都羡慕不已的事情,作为android程序员,何苦不用呢。

  5、理解Activity任务栈。
  非Activity的Context对象如果直接启动Activity会报错,这只是一个表面现象,真正起作用的其实是Activity任务栈机制。
  理解Activity任务栈机制以及Activity的各种启动方式,会帮助解决大部分页面关系错乱问题,以及应用互相掉起、任务栏进入应用、后台弹窗引起的各种问题。

  6、对于一些奇葩的第三方ROM,调用其非主流api的时候,可以使用反射。
  在适配一些第三方ROM的的时候,调用一些在开发环境中没有,但在运行环境中有的方法时,可以使用反射。比方说,华为双卡手机可能会提供获取第二块SIM卡信息的api,如果直接调用,在开发环境可能无法通过正常编译,用反射就没问题。这属于不得已而用反射的一种情况。

  7、SQLite的锁,是数据库级别的锁,也就是说同一个数据库的写操作无法并发执行。
  所以,在数据库设计的时候,如果表太多,尽量将没有关联的表拆到多个数据库文件中。

  8、Bitmap的内存占用问题。
  这是一个困扰2.X时代android程序员的问题。
  2.X时代Bitmap对象虽然存储在堆内存中,但是用了一个byte数组存储其像素信息。通过计数器来记录该像素信息被引用的个数。有人认为这个byte数组在native堆中,但事实上它也在堆中。
  只有在使用者调用recycle()后,Bitmap对象才会释放像素信息,才会在失去引用后,被垃圾回收机制销毁。再加上DVM的heap size有严格的阀值,所以在使用大量图片资源的时候,及其容易发生OOM。
  解决办法一般都是,用一个哈希表存储Bitmap对象的软引用,作为内存缓存,并在适当时机掉用其recycle()。
  3.0以上版本Bitmap对象可以通过垃圾回收机制完全销毁,理论上不用再调用recycle()。
参考技术A 参考如下 1、不要排斥新技术和新工具。  Android Studio 1.0 之后的版本,基本已经稳定到可以支持正常的工作开发的程度了。单纯就书写效率而言,Android Studio 带来的好处绝对大于它和Gradle的学习成本。JetBrains的IDE,用过都说好。  还有就是适当的提升targetSdkVersion到新版本。  2、代码设计方面的问题,大部分都能在Android系统源码里找到解决方案。  当设计一个新模块,或者实现一个新ui组件的时候,应该采用哪些设计模式、应该以哪种形式给外界提供接口之类的问题,大部分都可以参考Android系统的源码,找到实现方式。Google为安卓程序员提供了一座现成的宝库。  3、理解Android和Java内存管理方式,至少要理解垃圾回收和Java的引用。  就好比学OC就要先理解黄金法则一样,而java的内存管理,其实比OC要好理解多了。  这可能会帮助大大减少程序异步操作产生的空指针崩溃。也会帮助理解为什么滥用单例模式会导致内存的臃肿。还会帮助养成不用“+”去连接超大字符串的好习惯。  4、ContentProvider并不是只有在跨进程共享数据的才有用,把数据库表映射到一个独立的uri是Google鼓励的实现方式。  从设计上讲,用uri(统一资源标识符)去描述数据,肯定比sql语句要理想。  从效果上讲,用CursorLoader读取数据是让iOS程序员都羡慕不已的事情,作为android程序员,何苦不用呢。  5、理解Activity任务栈。  非Activity的Context对象如果直接启动Activity会报错,这只是一个表面现象,真正起作用的其实是Activity任务栈机制。  理解Activity任务栈机制以及Activity的各种启动方式,会帮助解决大部分页面关系错乱问题,以及应用互相掉起、任务栏进入应用、后台弹窗引起的各种问题。  6、对于一些奇葩的第三方ROM,调用其非主流api的时候,可以使用反射。  在适配一些第三方ROM的的时候,调用一些在开发环境中没有,但在运行环境中有的方法时,可以使用反射。比方说,华为双卡手机可能会提供获取第二块SIM卡信息的api,如果直接调用,在开发环境可能无法通过正常编译,用反射就没问题。这属于不得已而用反射的一种情况。  7、SQLite的锁,是数据库级别的锁,也就是说同一个数据库的写操作无法并发执行。  所以,在数据库设计的时候,如果表太多,尽量将没有关联的表拆到多个数据库文件中。  8、Bitmap的内存占用问题。  这是一个困扰2.X时代android程序员的问题。  2.X时代Bitmap对象虽然存储在堆内存中,但是用了一个byte数组存储其像素信息。通过计数器来记录该像素信息被引用的个数。有人认为这个byte数组在native堆中,但事实上它也在堆中。  只有在使用者调用recycle()后,Bitmap对象才会释放像素信息,才会在失去引用后,被垃圾回收机制销毁。再加上DVM的heap size有严格的阀值,所以在使用大量图片资源的时候,及其容易发生OOM。  解决办法一般都是,用一个哈希表存储Bitmap对象的软引用,作为内存缓存,并在适当时机掉用其recycle()。  3.0以上版本Bitmap对象可以通过垃圾回收机制完全销毁,理论上不用再调用recycle()。 参考技术B 1. 为Activity声明系统配置变更事件
系统配置变更事件是指转屏,区域语言发生变化,屏幕尺寸发生变化等等,如果Activity没有声明处理这些事件,发生事件时,系统会把Activity杀掉然后重启,并尝试恢复状态,Activity有机会通过onSaveInstanceState()保存一些基本数据到Bundle中,然后此Bundle会在Activity的onCreate()中传递过去。虽然这貌似正常,但是这会引发问题,因为很多其他的东西比如Dialog等是要依赖于具体Activity实例的。所以这种系统默认行为通常都不是我们想要的。
为了避免这些系统默认行为,就需要为Activity声明这些配置,如下二个是每个Activity必须声明的:
<activity android:configChanges="orientation|keyboardHidden">
几乎所有的Activity都要声明如上,为什么Android不把它们变成Default的呢?
2. 尽量使用Android的API
这好像是废话,在Android上面开发不用Android API用什么?因为Android几乎支持Java SE所有的API,所以有很多地方Android API与Java SE的API会有重复的地方,比如说对于文件的操作最好使用Android里面Context封装的API,而不要直接使用File对象:
Context.openFileOutput(String); // no File file = new File(String)
原因就是API里面会考虑到Android平台本身的特性;再如,少用Thread,而多使用AsyncTask等。
3. 要考虑到Activity和进程被杀掉的情况
如了通常情况退出Activity外,还有Activity因其他原因被杀的情况,比如系统内存过低,系统配置变更,有异常等等,要考虑和测试这种情况,特别是Activity处理重要的数据时,做好的数据的保存。
4. 小心多语言
有些语言真的很啰嗦,中文或英文很简短就能表达的事情到了其他语言就变的死长死长的,所以如果是wrap_content就可能把其他控制挤出可视范围; 如果是指定长度就可能显示不全。追答

也要注意特殊语言比如那些从右向左读的语言。
5. 不要用四大组件去实现接口
一是组件的对象都比较大,实现接口比较浪费,而且让代码更不易读和理解; 另外更重要的是导致多方引用,可能会引发内存泄露。
6. 用getApplication()来取Context当参数
对于需要使用Context对象作为参数的函数,要使用getApplication()获取Context对象当参数,而不要使用this,除非你需要特定的组件实例!getApplication()返回的Context是属于Application的,它会在整个应用的生命周期内存在,远大于某个组件的生命周期,所以即使某个引用长期持有Context对象也不会引发内存泄露。
7. 主线程只做UI控制和Frameworks回调相关的事。附属线程只做费时的后台操作。交互只通过Handler。这样就可以避免大量的线程问题。
8. Frameworks的回调不要做太多事情仅做必要的初始化,其他不是很重要的事情可以放到其他线程中去做,或者用Handler Schedule到稍后再做。
9. 要考虑多分辨率
至少为hdpi, mdpi, ldpi准备图片和布局。元素的单位也尽可能的使用dip而不要用px。
10. 利用Android手机的硬键
几乎所有的Android手机都有BACK和MENU,它们的作用是返回和弹出菜单,所以就不要再在UI中设计返回按扭和菜单按扭。很多优秀的应用如随手记和微信都有返回键,他们之所以有是因为他们都是从iOS上移植过来的,为了保存体验的一致,所以也有了返回和菜单。但这不够Android化,一个纯正的Android是没有必须重复硬键的功能的。

以上是关于Android 开发中,都有哪些坑需要注意的主要内容,如果未能解决你的问题,请参考以下文章

Android开发中需要注意哪些坑

Android WebView 在开发过程中都有哪些坑

Android WebView 在开发过程中都有哪些坑

Android爬坑之旅:软键盘挡住输入框问题的终极解决方案

打算使用laravel现有的数据库上做开发,会都有哪些坑

微信小程序开发都有哪些细节需要注意