Android 开发人员最常犯的 10 个错误:编程教程
已发表: 2022-03-11安卓。 这个平台有什么不喜欢的? 它是免费的、可定制的、发展迅速的,不仅可以在您的手机或平板电脑上使用,还可以在您的智能手表、电视和汽车上使用。
随着最新的 Lollipop 更新,Android 编程继续改进。 自最初的 AOSP 发布以来,该平台已经相当成熟,并将用户期望设置得相当高。 看看新的 Material 设计模式看起来有多棒!
有成千上万种不同的设备,具有不同的屏幕尺寸、芯片架构、硬件配置和软件版本。 不幸的是,细分是为开放性付出的代价,即使作为高级 Android 程序员,您的应用程序在不同设备上的失败方式也有数千种。
不管这么大的分割,大部分的bug其实都是因为逻辑错误而引入的。 只要我们掌握了正确的基础知识,这些错误就很容易避免!
这是一个 Android 编程教程,旨在解决 Android 开发人员最常犯的 10 个错误。
常见错误 #1:为 iOS 开发
令我高兴的是,这种 Android 错误如今已不常见了(部分原因是客户开始意识到 Apple 制定所有设计标准的日子早已一去不复返了)。 但是,我们仍然时不时地看到一个 iOS 克隆的应用程序。
不要误会我的意思,我不是 Android 编程布道者! 我尊重每一个推动移动世界向前发展的平台。 但是,现在是 2014 年,用户使用 Android 已经有一段时间了,他们已经习惯了这个平台。 将 iOS 设计标准推给他们是一个糟糕的策略!
除非有非常好的理由违反准则,否则不要这样做。 (谷歌一直这样做,但从不复制粘贴。)
以下是此 Android 错误的一些最常见示例:
- 你不应该制作静态标签,它们不属于底部(我指的是你的 Instagram)。
- 系统通知图标不应有颜色。
- 应用程序图标不应放置在圆角矩形内(除非那是您的实际徽标,例如 facebook)。
- 除了初始设置/介绍之外,启动画面是多余的。 不要在其他场景中使用它们。
- 列表不应该有插入符号。
这些只是可能破坏用户体验的许多其他小事情中的一小部分。
常见错误 #2:为您的 Android 设备开发
除非您正在为单个平板电脑构建信息亭/促销应用程序,否则您的 Android 应用程序可能不会在每台设备上看起来都很好。 以下是一些需要记住的 Android 编程技巧:
- 与密度无关的像素 (dp) 与普通像素 (px) 不同。
- 资源被多次包含以考虑不同的密度和方向。
- 9-patch drawables 被拉伸以适应屏幕。
确实有成千上万种可能的场景,但一段时间后,您会产生一种用少数案例涵盖所有场景的感觉。
你没有成千上万的设备? 不是问题。 Android Emulator 在复制物理设备方面非常出色。 更好的是,试试 Genymotion,它速度极快,并带有许多不同的流行预设设备。
另外,您是否尝试过旋转设备? 所有的地狱都可以挣脱……
常见错误#3:不使用意图
Intent 是 Android 的关键组件之一。 这是一种在应用程序的不同部分之间传递数据的方式,或者更好的是,在系统上的不同应用程序之间传递数据。
假设您有一个图库应用程序,可以通过 SMS 共享指向某些图像的下载链接。 这两个选项中哪一个看起来更合乎逻辑?
选项1:
请求 SEND_SMS 权限。
<uses-permission android:name="android.permission.SEND_SMS" />- 编写您自己的代码以使用
SmsManager发送短信。 - 向您的用户解释为什么您的图库应用需要访问可能需要花钱的服务,以及为什么他们必须授予此权限才能使用您的应用。
选项 2:
启动 SMS Intent 并让专为 SMS 设计的应用程序完成工作
Intent sendIntent = new Intent(Intent.ACTION_VIEW); sendIntent.setData(Uri.parse("sms:" + telephoneNumber)); sendIntent.putExtra("sms_body", x); startActivity(sendIntent);
如果您有任何疑问,最好的解决方案是选项 2!
这种方法几乎可以应用于任何事情。 分享内容、拍照、录制视频、挑选联系人、添加事件、打开与原生应用程序的链接等。
除非有充分的理由进行自定义实现(例如,应用过滤器的相机),否则请始终在这些场景中使用 Intent。 它将为您节省大量编程时间,并AndroidManifest.xml不必要的权限。
常见错误 #4:不使用片段
前段时间在 Honeycomb 中,Android 引入了Fragments的概念。 将它们视为单独的构建块,它们具有自己的(相当复杂的)生命周期,存在于 Activity 中。 它们对优化各种屏幕有很大帮助,它们很容易由其父活动管理,可以随意重用、组合和定位。
为每个应用程序屏幕启动一个单独的活动是非常低效的,因为系统会尽可能长时间地将它们保存在内存中。 杀死一个不会释放其他人使用的资源。
除非您想深入了解 Android 核心并阅读这篇反对使用 Fragment 的文章,否则您应该尽可能使用 Fragment。 它基本上说片段和游标加载器具有良好的预期目的,但实施不佳。
常见错误 #5:阻塞主线程
主线程只有一个目的:保持用户界面响应。
尽管测量我们的眼睛/大脑可以感知的帧速率背后的科学是复杂的并且受很多因素的影响,但一般规则是任何低于 24 fps 且延迟大于 100 毫秒的东西都不会被认为是流畅的。
这意味着用户的操作会有延迟的反馈,您编写的 Android 应用程序将停止响应。 剥夺用户对应用程序的控制会导致沮丧,沮丧的用户往往会给出非常负面的反馈。
更糟糕的是,如果主线程被阻塞了一段时间(活动 5 秒,广播接收器 10 秒),就会发生 ANR。

这在 Android 2.x 中很常见,以至于在较新的版本上,系统不允许您在主线程中进行网络调用。
为避免阻塞主线程,请始终将工作线程/后台线程用于: 1. 网络调用 2. 位图加载 3. 图像处理 4. 数据库查询 5. SD 读/写
常见错误 #6:重新发明轮子
“好吧,我不会使用主线程。 我将编写自己的代码,在后台线程中与我的服务器通信。”
不! 请不要那样做! 网络调用、图像加载、数据库访问、JSON 解析和社交登录是您在应用程序中最常做的事情。 不仅是您的,还有所有应用程序。 有一个更好的办法。 还记得 Android 作为一个平台是如何成熟和成长的吗? 以下是示例的快速列表:
- 使用 gradle 作为构建系统。
- 使用 Retrofit / Volley 进行网络调用。
- 使用 Picasso 进行图像加载。
- 使用 Gson / Jackson 进行 JSON 解析。
- 使用社交登录的常见实现。
如果您需要实现某些东西,很可能它已经被编写、测试和广泛使用。 在编写自己的代码之前,先做一些基础研究并阅读一些 Android 编程教程!
常见错误 #7:不假设成功
伟大的。 我们了解到,有一种更好的方法来处理长时间运行的任务,为此我们正在使用有据可查的库。 但用户仍需等待。 这是不可避免的。 包裹不会立即发送、处理和接收。 有往返延迟,有网络故障,有包裹丢失,有梦想破灭。
但这一切都是可以衡量的。 成功的网络调用比不成功的更可能。 那么为什么在处理成功的请求之前等待服务器响应呢? 假设成功并处理失败要好得多。 因此,当用户点赞帖子时,点赞计数会立即增加,并且在不太可能发生呼叫失败的情况下,会通知用户。
在这个现代世界中,期望立即得到反馈。 人们不喜欢等待。 孩子们不想坐在教室里获取未来回报不确定的知识。 应用程序必须适应用户的心理。
常见错误 #8:不理解位图
用户喜欢内容! 特别是当内容格式良好且看起来不错时。 例如,图像是非常好的内容,主要是因为它们每张图像可以传达一千个单词。 它们还消耗大量内存。 很多内存!
在屏幕上显示图像之前,必须将其加载到内存中。 由于位图是执行此操作的最常见方式,因此我们将为整个过程提供 Android 编程指南:
假设您想在屏幕上显示您刚刚用相机拍摄的图像。 为此所需的总内存使用以下公式计算: memory_needed_in_bytes = 4 * image_width * image_height;
为什么是4? 好吧,最常见/推荐的位图配置是ARGB_8888 。 这意味着对于我们绘制的每个像素,我们需要在内存中为 alpha、红色、贪婪和蓝色通道保留 8 位(1 个字节),以便正确显示它。 还有其他选择,例如RGB_565配置,它需要的内存是ARGB_8888的一半,但会失去透明度和颜色精度(同时可能会添加绿色色调)。
假设您有一台全新的设备,配备全高清屏幕和 12 MP 摄像头。 您刚刚拍摄的图片大小为 4000x3000 像素,显示它所需的总内存为: 4 bytes * 4000 * 3000 = 48 MB
48 MB 的 RAM 仅用于单个图像!? 好多啊!
现在让我们考虑屏幕分辨率。 您试图在具有 1920x1080 像素的屏幕上显示 4000x3000 图像,在最坏的情况下(全屏显示图像)您不应分配超过4 * 1920 * 1080 = 8.3 MB的内存。
始终遵循有效显示位图的 Android 编程技巧:
- 测量显示图像的视图。
- 相应地缩放/裁剪大图像。
- 仅显示可以显示的内容。
常见错误 #9:使用深度视图层次结构
布局在 Android 中有一个 XML 表示。 为了绘制内容,需要解析 XML,需要测量屏幕,并且需要相应地放置所有元素。 这是一个需要优化的资源和耗时过程。
这就是 ListView(以及最近的 RecyclerView)的工作方式。
如果一个布局已经膨胀一次,系统就会重用它。 但是,膨胀布局必须在某个时候发生。
假设你想用图像制作一个 3x3 的网格。 这样做的一种方法是包含 3 个具有相同权重的LinearLayout的垂直LinearLayout ,每个它们都包含 3 个具有相同权重的ImageViews 。
我们用这种方法得到了什么? “嵌套权重对性能不利”的警告。
Android 编程界有一句我刚刚编造出来的说法: “只要不费吹灰之力,所有层次结构都可以扁平化” 。
在这种情况下, RelativeLayout或GridLayout将有效地替换嵌套的LinearLayouts 。
常见错误 #10:未将 minSdkVersion 设置为 14
好吧,这不是一个错误,但这是一种不好的做法。
Android 2.x 是开发这个平台的一个巨大里程碑,但有些东西应该被抛在后面。 支持旧设备会增加代码维护的复杂性并限制开发过程。
数字很清楚,用户已经继续前进,开发人员不应该落后。
我知道这不适用于一些使用旧设备的大市场(例如印度),并且在 Facebook 应用程序上将minSdkVersion设置为 14 意味着让数百万用户没有他们最喜欢的社交网络。 但是,如果您刚开始并试图为您的用户创造美好的体验,请考虑消除过去。 没有资源的用户,或者觉得需要升级他们的设备/操作系统的用户,没有动力去尝试你的 Android 应用程序的高级版本并最终花钱购买。
包起来
Android 是一个发展迅速的强大平台。 期望用户跟上步伐可能是不合理的,但对于 Android 开发人员来说,这样做至关重要。
了解 Android 不仅仅在我们的手机或平板电脑上更为重要。 它在我们的手腕上,在我们的客厅里,在我们的厨房里,在我们的汽车里。 在我们开始扩展之前,掌握正确的基础知识至关重要。
