Android 开发小提示集合

matt0614 9年前

来自: http://blog.chengyunfeng.com/?p=867

本篇文章记录了各种 Android 开发过程中可能会用到的小技巧,有些可能你已经知道,有些可能你第一次听说。使用这些提示可以帮助提高开发效率、避免潜在的问题。

提示1

AndroidStudio 包含了一个非常方便的图标生成器。支持各种风格的图标生成,比如 通知图标、启动图标、tab 图标等。并且支持 png 和 svg 格式的图标。该工具位于菜单:[File] >[New] >[Image Asset] 和 [File] >[New] >[Vector Asset]

提示2

想要在 Gradle 中执行单个测试? 下面的命令可以帮助你:

./gradlew testDebug –tests=’*.

提示3

在开发测试阶段使用 strict mode 来确保您没有在主线程中干了不该干的事,比如 访问 磁盘文件和网络操作等。

Java

if (BuildConfig.DEBUG) {   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()         .detectAll()         .penaltyLog()         .build());   StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()         .detectAll()         .penaltyLog()         .penaltyDeathOnNetwork()         .build());  }
if (BuildConfig.DEBUG) {   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()        .detectAll()        .penaltyLog()        .build());   StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()        .detectAll()        .penaltyLog()        .penaltyDeathOnNetwork()        .build());  }
</div>

发布版本中记得关闭该功能, 否则会影响性能。

提示4

在使用 Picasso 图片库的时候,可以通过 RequestTransformer 来添加请求图片 url 的参数。例如添加需要请求图片的尺寸信息。

提示5

如果在 Android activity manifest 文件中使用了 android:windowSoftInputMode=”adjustResize” 属性。当软键盘出现的时候,则 ScrollView (或者其他可以滚动的 ViewGroup)会缩小其高度。 但是 如果你在 Activity theme 中使用 android:windowFullscreen=”true” 属性,则 ScrollView 高度不会改变,应用该属性强制其高度为 屏幕高度。 同样 使用 android:fitsSystemWindows=”false” 高度也不会改变。

提示6

如果 Android 系统在更新 Webview 的时候,您的应用如果使用了 Webview 并且正在运行则会导致您的应用崩溃。 http://stackoverflow.com/questions/29575313/namenotfoundexception-webview

提示7

Material Design(纸墨设计)中定义了标准的 padding 和 margin 值,除非您有特殊的要求可以不按照该规范设计UI。 否则你可以通过 https://play.google.com/store/apps/details?id=com.faizmalkani.keylines 应用来检测你的 UI 是否准守该规范。

提示8

RecyclerView 的 getChildLayoutPosition 返回子元素的位置,如果该元素从 Adapter 中删除了 但是该元素在 UI 上还存在(比如滑动删除, 正在做删除的动画),则 getChildLayoutPosition 依然会返回正确的 位置信息。

提示9

如果需要空集合对象的时候,请使用 Collections.emptyList() 和 Collections.emptySet()。该函数确保生成一个单例的空集合。

提示10

如果你使用 ZXing 库的 QRCodeWriter 来生成二维码。如果生成的图片比较大则需要很多时间来生成图片。你可以使用参数 0x0 作为尺寸信息,则 QRCodeWriter 会返回一个 BitMatrix 对象,里面包含了生成该二维码所需要的最少的像素信息(每个块为一个像素)。然后你可以把该 BitMatrix 数据写到 BitmapDrawable 对象上,然后把该 BitmapDrawable 用作 View 的背景。注意:需要调用 drawable 的setFilterBitmap(false) 来避免缩放。

Java

BitMatrix matrix = new QRCodeWriter().encode("content here", BarcodeFormat.QR_CODE, 0, 0);  int height = matrix.getHeight();  int width = matrix.getWidth();  Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);  for (int x = 0; x < width; x++) {  for (int y = 0; y < width; y++) {  bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.TRANSPARENT);  }  }  BitmapDrawable qrCodeDrawable = new BitmapDrawable(getResources(), bmp);  qrCodeDrawable.setFilterBitmap(false);  imgQrCode.setBackground(qrCodeDrawable);
BitMatrixmatrix = new QRCodeWriter().encode("content here", BarcodeFormat.QR_CODE, 0, 0);  int height = matrix.getHeight();  int width = matrix.getWidth();  Bitmapbmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);  for (int x = 0; x < width; x++) {  for (int y = 0; y < width; y++) {  bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.TRANSPARENT);  }  }  BitmapDrawableqrCodeDrawable = new BitmapDrawable(getResources(), bmp);  qrCodeDrawable.setFilterBitmap(false);  imgQrCode.setBackground(qrCodeDrawable);
</div>

上面示例中使用了参数 Bitmap.Config.ARGB_4444,这样生成的图片背景为透明的。如果你只需要黑白的图片,则可以使用 Bitmap.Config.RGB_565。另外为了保险起见,还可以使用 BitMatrix matrix = new QRCodeWriter().encode(“content here”, BarcodeFormat.QR_CODE, 10, 10); ,这样可以预防 ZXing 停止支持 0 0 参数。

提示 11

使用 adb hell 来替代 adb shell 会有意想不到的收获。(Windows 用户没啥收获 ^_^)

提示 12

TextUtils.concat() 函数的参数为 CharSequence ,并且保留了每个CharSequence 中的 spans 设置。

提示 13

当批量操作数据库的时候,可以使用 SqliteDatabase 的 beginTransaction() 和 endTransaction() 函数。 记得调用 setTransactionSuccessful() 函数,否则的话,在endTransaction() 执行的时候,所有的操作都会回滚到之前的状态。

提示 14

Sqlite 数据库很多操作都有一些限制,这里有详细的描述:https://www.sqlite.org/limits.html 。请看看这些限制做到心中有数。

提示 15

如果一个 View 不在界面最上面不应该接受点击事件,则可以通过 setFilterTouchesWhenObscured 函数来做到这点。 这样可以避免木马软件窃取信息: http://developer.android.com/reference/android/view/View.html#setFilterTouchesWhenObscured(boolean)

提示 16

当显示加载内容ProgressBar 的时候,考虑使用 ContentLoadingProgressBar

/**

* ContentLoadingProgressBar implements a ProgressBar that waits > a minimum time to be

* dismissed before showing. Once visible, the progress bar will > be visible for

* a minimum amount of time to avoid “flashes” in the UI when an > event could take

* a largely variable time to complete (from none, to a user perceivable amount)

*/

</div>

https://developer.android.com/reference/android/support/v4/widget/ContentLoadingProgressBar.html

提示 17

OSX 系统文件名字是不区分大小写的,但是终端窗口中是区分的。当你把 myClass.java 重命名为 MyClass.java 会有问题的。 需要注意该问题。

提示 18

使用 Picasso 的resize() 功能的时候,如果你把其中的一个参数设置为 0,则 Picasso 会保持该图片的长宽比来计算该值。

提示 19

View 只有带有 ID 的时候才能保持其状态。

提示 20

AppCompatDialog.setStyle(STYLE_NO_TITLE, …) 其实并没有用,并抛出一个异常。你应该创建一个 Style 并且把该 style 作为 对话框的 构造函数参数。

提示 21

在 Android 6.0+ 系统上通过 照相机应用的 Intent 来获取照片的时候,需要 Camera 权限才能获取到返回的图片数据。

提示 22

ViewPager 的 onPageScrolled 回调函数可以获取到当前页面滚动的位置,使用该信息可以修改 tab 的显示状态。

提示 23

使用 dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 可以在有输入框的对话框显示的时候不显示软键盘。

提示 24

如果你覆盖了 DialogFragment 的 onCreateDialog 函数而不是 onCreateView 。则 onViewCreated 函数不会被调用。

提示 25

库项目的 BuildConfig.DEBUG 和 app 的 BuildConfig.DEBUG 不一样。

提示 26

adb longcat 和 adb logcat -v long 是一样的。

提示 27

当调用一个服务器API 并显示一个 dialog fragments 的时候,请注意该操作可能发生在 activity 的状态已经保存的时候,这样会抛出异常。解决方式:只在 onResume() 和 onPause() 之间显示对话框。

提示 28

在 build.gradle 的 defaultConfig 中添加:

archivesBaseName = “halogen-$versionName-$versionCode”

就可以在输出的 apk 中添加 版本名字和版本代号字段了。

提示 29

想要自动删除 unaligned .apks 文件则可以使用如下的代码:

Java

applicationVariants.all { variant ->     variant.assemble.doLast {         variant.outputs.each { output ->             File unaligned = output.packageApplication.outputFile;             File aligned = output.outputFile             if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {                 println "deleting " + unaligned.getName()                 unaligned.delete()             }         }     }  }
applicationVariants.all { variant ->    variant.assemble.doLast {        variant.outputs.each { output ->            Fileunaligned = output.packageApplication.outputFile;            Filealigned = output.outputFile            if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {                println "deleting " + unaligned.getName()                unaligned.delete()            }        }    }  }
</div>

来源: willowtreeapps

</div>