目录
1. String==null、String.isEmpty()、TextUtils.isEmpty(String)区别
- String == null
仅判断字符串是否为空
- String.isEmpty()
判断字符串长度是否为0,若字符串为空会抛出空指针异常
源码:
@Override
public boolean isEmpty() {
return value.length == 0;
}
测试代码:
public class test {
public static void main(String[] args) {
String s1 = "";
String s2 = null;
//判断s1
if(s1.isEmpty()){
System.out.println("The length of s1 is 0");
}else{
System.out.println("The length of s1 is not 0");
}
if(s1==null){
System.out.println("s1 is null");
}else{
System.out.println("s1 is not null");
}
//判断s2
if(s2==null){
System.out.println("s2 is null");
}else{
System.out.println("s2 is not null");
}
if(s2.isEmpty()){
System.out.println("The length of s2 is 0");
}else{
System.out.println("The length of s2 is not 0");
}
}
}
运行结果:
- TextUtils.isEmpty(String)
Android中经常使用TextUtils.isEmpty()来判断字符串是否为空,将进行字符串判空和字符串长度判断
源码:
/**
* Returns true if the string is null or 0-length.
* @param str the string to be examined
* @return true if str is null or zero length
*/
public static boolean isEmpty(CharSequence str) {
if (str == null || str.length() == 0)
return true;
else
return false;
}
2. Bitmap和BitmapFactory的使用方法
- 构造Bitmap对象
方法名(只列出部分方法) | 用法说明 |
---|---|
createBitmap(Bitmap src) | 复制位图 |
createBitmap(Bitmap src,int x ,int y,int w,int h) | 从源位图src的指定坐标(x,y)开始,截取宽w,高h的部分,用于创建新的位图对象 |
createScaledBitmap(Bitmap src,int w ,int h,boolean filter) | 对源位图src缩放成宽为w,高为h的新位图 |
createBitmap(int w ,int h,Bitmap.Config config) | createBitmap(int w ,int h,Bitmap.Config config) |
createBitmap(Bitmap src,int x ,int y,int w,int h,Matrix m,boolean filter) | 从源位图src的指定坐标(x,y)开始,截取宽w,高h的部分,按照Matrix变换创建新的位图对象 |
- 通过BitmapFactory工厂类的static Bitmap decodeXXX()
方法名 | 参数及解释 |
---|---|
decodeByteArray(byte[] data, int offset, int length) | 从指定字节数组的offset位置开始,将长度为length的数据解析成位图 |
decodeFile(String pathName) | 从pathName对应的文件解析成的位图对象 |
decodeFileDescriptor(FileDescriptor fd) | 从FileDescriptor中解析成的位图对象 |
decodeResource(Resource res,int id) | 根据给定的资源Id解析成位图 |
decodeStream(InputStream in) | 把输入流解析成位图 |
3. AndroidManifest.xml中meta-data元素详解
<meta-data android:name = "string"
android:resource = "resource specification"
android:value = "string"/>
meta-data采用name-value对的格式给其父组件提供任意可选的数据。一个组件可包含多个子元素,所有这些元素中定义的值会被收集到一个Bundle对象中,并且提供给组件的PackageItemInfo.metaData属性字段,可以通过PackageItemInfo.metaData字段获取meta-data配置的数据。
- android:name
项目的唯一名称,使用Java样式的命名规则,可确保名称唯一性。
- android:resource
该属性定义了一个要引用的资源,资源的ID会跟android:name指定的项目进行关联,通过Bundle.getInt()获取ID。
- android:value
分配给该项目一个值,根据类型获取。
4. 混淆规则详解
Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具。在需要在工程应用目录的gradle文件中设置minifyEnabled为true,在pro guard-rules.pro文件中加入混淆规则。
对release版本进行混淆处理,示例:
android{
...
buildTypes{
release{
minifyEnabled ture
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
}
- ProGuard作用
默认开启压缩、优化、混淆功能
- 压缩
减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(优化后可能会再次暴露一些未被使用的类和成员)
-dontshrink
关闭压缩
- 优化
在字节码级别执行优化,让应用运行得更快
-dontoptimize
关闭优化
-optimizationpasses n
表示proguard对代码进行迭代优化的次数,Android一般为5
- 混淆
增大反编译难度,类和类成员会被随机命名,除非用keep保护。
-dontobfuscate
关闭混淆
- 基本规则
保留 | 防止被移除或者被重命名 | 防止被重命名 |
---|---|---|
类和类成员 | -keep | -keepnames |
仅类成员 | -keepclassmemebers | -keepclassmembernames |
若拥有某成员,保留类和类成员 | -keepclasseswithmembers | -keepclasseswithmembernames |
-keep class com.example.xxx.*
只保持该包下的类名,而子包下的类名还是会被混淆
-keep class com.example.xxx.**
表示把本包和所有子包下的类名都保持
注:以上方法虽类名未混淆,但是里面的具体方法和变量命名还是变了
-keep class com.example.xxx.** { *; }
表示保持里面的内容不被混淆
-keepclasseswithmembers class * implements com.example.xxx.xx { public <methods>; }
使用extend、implement保护继承或引用了指定类和接口的类不被混淆,{}中指定特定内容不被混淆
<init>; //匹配所有构造器
<fields>; //匹配所有域
<methods>; //匹配所有方法方法
//修饰符
private
public
native
- 注意事项
- jni方法不可混淆
- 反射用到的类不混淆(否则反射可能出现问题)
- AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入。
- 与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象
- 使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则
- 有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样
- Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常
- 使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
5. lib和libs的区别
放在lib中的是被reference的,放在libs中的是被include的。
放在libs中的文件会自动被Eclipse所include。所以不要把API放到libs里去。
lib的内容是不会被打包到APK中,libs中的内容是会被打包进APK中。