Android开发随手记

Posted 承諾@理想國

tags:

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

本文是作者在android开发实践中的随手速记,记录一些小问题的解决方案和注意事项,持续更新。

 以下是速记内容,若有不严谨的地方,望小伙伴们指出。

1.Module 不生成R文件,可尝试取消对该Module的引用,
取消后AS会再次编译工程,看看此时能否生成R。

2.Activity theme设置错误时,会出现:
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams
cannot be cast to com.android.internal.widget.ActionBarOverlayLayout$LayoutParams
此时,需要为Activity/Application指定带ActionBar的系统样式,或让自定义的Theme集成自带ActionBar
的系统样式,当然也可以改用普通Activity类,而非使用Actionbar的Activity子类。

3.java.lang.IllegalArgumentException: NaN is not a valid double value as per JSON
specification. To override this behavior, use GsonBuilder.
serializeSpecialFloatingPointValues() method.

4.AndroidStudio中引用Module时,Module中同名的资源会被App中的资源替换,
利用这一点可以实现自定义资源而不修改Module。目前只试过String.

5.Dagger 环境配置(可解决不能生成Dagger类的情况):http://www.itnose.net/detail/6353446.html
http://stackoverflow.com/questions/29562347/how-do-i-configure-intellij-gradle-to-use-dagger-2-0

6.Android TouchDelegate 只能扩展同一个ViewGroup中的一个View的响应范围。

7.Baidu Map V3.7 MKOfflineMap 下载完成后不可调用destroy方法(也许下载完成后百度在做一些善后事宜),
否则离线地图可能无法正常使用。另外此版本的MKOLUpdateElement.status永远为1,不可靠~

8.ART JNI、GC http://developer.android.com/guide/practices/verifying-apps-art.html


9.IDEA更新JDK至1.8(From1.7),编译代码时出现:
Error:(18, 6) java: -source 1.3 中不支持注释
(请使用 -source 5 或更高版本以启用注释)
打开Project Structure,在Project栏中找到Project language level,修改成1.3以上版本即可。

10.当为Activity写了Portrait和LandScape两种布局时,在布局文件根节点上添加Tag值,在运行时读取可区分Portrait和LandScape。

11.打开应用,使用adb shell dumpsys activity top,可以查看应用Activity的信息,也可以获取包名。

12.启动Activity的时候,设置Flag,Intent.setFlags(Intent.Flag_Activity_New_Task|Intent.Flag_Activity_Clear_Task)可以清空BackStack。

13.Context.createPackageContext(pkgName,flags)可以根据包名创建另一个Application的context,前提是二者的shareUserId和Signature要相同,这样就
两个应用就会运行在同一个Process中,主应用就可以访问附属应用的Resources和Classloader(context.getClassloader.load(className)).安装在设备中的每一个apk程序,Android系统会给其
分配一个单独的用户空间,其中android:shareUserId就是对应一个Linux用户ID,并且为它创建一个沙箱,以防止与其它应用程序产生影响。用户ID
在应用程序被安装到设备中时分配。通过SharedUserid,拥有同一个Userid的多个APK可以配置成运行在同一个进程中,所以默认就是可以互相访问任
意数据,也可以配置成运行在不同的进程中, 同时可以访问其APK的数据目录下的资源(图片,数据库和文件),就像访问本程序的数据一样。

14.Activity View 层级:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0331/1608.html

15.动态加载机制:http://blog.csdn.net/jiangwei0910410003/article/details/17679823

16.继承的坏处:Super方法里引用了可被子类复写的方法时,该方法也会被子类改写(调用Super.method也无效)。

17.Android 6.0 File.mkdirs()无效,是因为权限控制,可动态申请权限:http://stackoverflow.com/questions/32225506/android-6m-permission-issue-create-directory-not-working

18.为一个Resources创建LayoutInflater用于inflate该Resource中的layout,需要Extend ContextThemeWrapper实现一个ResourcesContext,
然后使用 LayoutInflater.from(Context).cloneInContext(ResourceContext);

19.ListView Item中的可点击控件

20.使用Navigator来导航可以避免Activity相互引用,在Activity中写获取启动它的Intent的方法可以避免对外定义传参Key。

21.使用android.R.id.content可以获取Activity的根元素。

22.Java包内外层需要互相引用,没有内层可以直接使用外层或者外层可以直接使用内层之说。

23.在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,支持了String。

24.解决动态加载SurfaceView闪屏问题的两种方式:一,getWindow().setFormat(PixelFormat.TRANSLUCENT); 二,在布局中添加一个
不可见的SurfaceView。

25.使用Fragment.onActivityCreated()来retrieve view和restore view state。

26.Android 通过Intent.setComponent(new ComponentName(PkgName,ClassName))可以启动另一个Apk的Activity;通过new
DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)可加载执行Jar/Apk中的代码。

27.ScrollView中内容不足以填充到全屏时,需要添加android:fillViewport="true"来让ScrollView填满全屏。

28.Apk的Resource ID信息没有放在classes.dex中,放在Resources.arsc中?? See:http://blog.csdn.net/luoshengyang/article/details/8744683
和http://blog.csdn.net/luoshengyang/article/details/8806798

29.Android浮点运算:嵌入式处理器通常没有支持浮点运算,所有对"float"和"double"的运算都是通过软件
实现的。一些基本的浮点运算,甚至需要毫秒级的时间才能完成。甚至是整数,一些芯片有对乘法的硬件支
持而缺少对除法的支持。这种情况下,整数的除法和取模运算也是由软件来完成的。所以当你在使用哈希表
或者做大量数学运算时一定要小心谨慎。

30.Git 只clone一个分支:git clone -b <branch> <repo>

31.Java 1.5开始支持静态引用,可以直接引用静态方法,省略调用静态方法时需要写类名的工作。使用 import static <class>.* 可引入所有静态方法。

32.Android Activity中 getApplicationContext!=getBaseContext(),后者是为每个Activity重新创建的一个ContextImpl,Activity本身是一个
ContextThemeWrapper,它依靠ContextImpl来完成实际的工作。

33.Thread的looper和MainThread的MainLooper都是直接new出来的,本质上没有区别,启用了Looper的Thread创建的Handler可以执行UI操作
,但是这里的操作如果耗时太久的话(如sleep>100ms),容易崩溃(待验证,当耗时操作在前易崩溃)。

34.ActivityManager.getRunningTasks(1).get(0).topActivity()可获取前台应用的Activity componentName。

35.如果使用Application的Context来bindService,Service就会跟Application的生命周期一样,而不会受Activity的生命周期影响。如果是用某个
Activity的Context来绑定Service,这个Service的生命周期就受到这个Activity(而非App的其他Activity)的生命周期影响,并且无需调用UnbindService。


36.Exception raised during rendering: com/android/util/PropertiesMap (Details),在渲染预览界面更改渲染工具版本即可。

37.AndroidStudio Ignore Files:
.idea
.gradle
build/
local.properties
*.iml

38.Android 切图中不规则的图片(两头纯圆按钮)或纯规则图片(纯圆,正方形?)无法做.9拉伸,做成Bitmapdrawable(<bitamp/>)可以解决。

39.Android添加悬浮窗显示,需要使用Application的Context,如若不能显示在所有应用上层,则需使用Service?

40.SurfaceView黑屏:(1)getWindow().setFormat(PixelFormat.TRANSLUCENT);

41.Gson序列化时排除字段:http://www.tuicool.com/articles/v2eIrqz

42.引入关联表来关联两个表之间的关系。

43.Gson 转换List<T>时,需要使用new TypeToken<List<String>>(){}.getType(),特别注意TypeToken后面的大括号。

44.以文件夹方式隔离用户数据,将用户数据(包括数据库)都放到带用户信息的文件夹下面。

45.Android 无法实现不影响后面操作的悬浮操作?

46.使用wait()和notify()时一般是为了同步线程,但是要注意,如果所调用的方法没有开启异步线程,可能会直接返回,这时候在方法调用之后
使用的wait()就会一直等待异步回调来notify,然而回调其实早就已经在方法栈中发生,这样就会导致线程一直等待。如果开启了异步线程,那wait()一定会等到notify的到来。

47.Java 使用泛型时,支持自动以泛型的具体类型来命名参数,只要让泛型对应的参数名与泛型名一样(不区分大小写)就可以做到。

48.Sqlite 查询为空的字段 Field IS NULL, 查询不为空的字段 Field IS NOT NULL。

49.ImageView tint in xml and setColorFilter 可以对图片进行着色,可用于改变图标的颜色,使用PorterDuff.Mode.CLEAR时,还可以隐藏绘制内容。

50.FileOutputStream.getChannel().lock() 可以获得一个FileLock以锁定文件。

51.解决Gradle DSL method not found: ‘android()’:删除Project的build.gradle文件中的:android{}即可。See:http://www.hloong.com/?p=100

52.ListView 的Item中有可点击元素时,需将可点击元素的Focusable和FocusableInTouchMode属性设置为false,并为ListView设置android:descendantFocusability="blocksDescendants"
这样按钮和Item都可以点击。

53.Root 原理:http://www.myhack58.com/Article/html/3/92/2013/36574.htm

54.requestWindowFeature()用来动态的决定Window的特性,而这个行为发生在setContentView之前,所以必须要在setContentView之前设置。如request
WindowFeature(Window.FEATURE_NO_TITLE)之后,Window中的DecorView就不会生成TitleView部分,而只生成ContentView部分。

55.Android Style中使用自定义View属性时,不用加任何命名空间(如android:xxx),直接使用属性名即可

56.PopupWindow点击外部消失,只需设置background即可: setBackgroundDrawable(new BitmapDrawable())

57.Sqlite不可在事务中开启另一个事务,否则这个事务操作无效。

58.new SimpleDateFormat("yyyy-M-d hh:mm").format(date)可以去0。

59.View 在绑定后,从View树中移除后再添加,绑定的数据依然有效。

60.EditText设置inputType="numberSigned"时可以输入负数。

61. <item name="android:imeOptions">flagNoExtractUi</item>可禁止输入法开新界面全屏输入

62.Sqlite 关联查询:SELECT A.*,B.name FROM Task AS A ,Project AS B WHERE A.Status<=‘2‘

63.Adapter.getItemViewType()返回的Type范围应该是(0,ItemViewTypeCount]

64.Fatal signal 11 (SIGSEGV), code 0, fault addr 0x61b6 in tid 25110 (RenderThread) 跟硬件加速有关,避免设置
View.setLayerType(View.LAYER_TYPE_HARDWARE, null),出现问题时可在Manifest中禁用硬件加速:<android:hardwareAccelerated="false">

65.NDK_PROJECT_PATH=null,在app/build.gradle的android{}中添加
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir ‘src/main/libs‘
}
即可解决。

66.计算大数值时容易溢出,最好转换为大数值类型计算:如long EXPIRE_LOGIN =90* 24 * 60 * 60 * 1000 结果为负数,应改为:
long EXPIRE_LOGIN =90L* 24 * 60 * 60 * 1000;

67.fitsSystemWindows实现沉浸式:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1122/3712.html

68.app:layout_behavior="@string/bottom_sheet_behavior"

69.Application 中的OnTrimMemory用于系统恢复内存,此时可将一些不重要的内存缓存释放掉。

70.ImageView adjust to Image,user adjustViewBounds=true and maxWidth/maxHeight of ImageView.

71.<item name="android:windowDrawsSystemBarBackgrounds">false</item> 控制内容是否渲染到底部栏下面

72.Sqlite DISK IOERROR WRITE,是因为临时目录问题,可以通过设置之解决问题:
http://blog.csdn.net/u011453773/article/details/50731331

73.Android 调用系统分享:http://stackoverflow.com/questions/30518321/on-android-m-how-to-configure-the-direct-share-capabilities-image-text-an/30721038#30721038

74.获取Android 的ContentView的容器可以通过它的ID: Window.ID_ANDROID_CONTENT。

75.Java中Object的hashcode返回一个int的hash值。默认情况下,Object中
的hashCode() 返回对象的32位jvm内存地址。也就是说如果对象不重写该方
法,则返回相应对象的32为JVM内存地址。equals方法返回true的两个Objec
t应该返回相同的hashcode。所以一般Object的子类在是想equals方法和hashcode
方法的时候,要么同时实现,要么都不实现。这对于键值对使用时应该很关
键。重写equals和hashcode时,可以使用IDE提供的方法,安全高效。参考:
https://www.oschina.net/question/82993_75533 同时注意ORM的情况。

76.Collections.synchronizedXXX(),是对所有的传入对象加了同步锁。

77.HashMap 操作都是通过数组找链表头结点,key用于hash后找到数组index。
它的containskey也会通过key的hash找到对应链表头结点,然后遍历,但是containsValue因为不知道
key,无法hash找到index,所以是按数组顺序依次遍历每一个链表查找,效率较低。

78.AndroidStudio 编译报错: Error:java.lang.NullPointerException
(no error message),删除工程目录下.gradle文件,重启就好。

79.GreenDao局限性:不能兼容模型的继承关系,无法将父类的字段生成数据库字段,如果父类和子类都有
都建了表,Dao之间没有继承关系。此时可能考虑合并连个表。

80.serialVersionUID 的意义:http://lenjey.iteye.com/blog/513736

81.ScrollView 嵌套GridView或者ListView,可以重写onMeasure方法,设置
测量高度为最大值,测量模式为AT_MOST,实现跟随ScrollView滚动。此时如果
遇到布局自动滚动到GridView所在位置,禁用GridView focus即可。

82.HttpUrlConnection 出现EOFException,据说是当响应的InputStream 是 GZIPInputStream时,会造成 HTTP HEAD 的冲突,此处应该是个Bug,原因可以参考以下网址:
https://code.google.com/p/android/issues/detail?id=24672 , 可以通过设置 connection.setRequestProperty( "Accept-Encoding", "" )解决.

83.RecyclerView的Item布局中不能直接使用View,需使用具体的View。否则可能会报CreateViewFromTag Nullpointer。

84.在返回集合的方法中,不建议返回null,而是返回Collections.emptyxxx。

85.List泛型参数的子类和父类的转化,可以先将待转换的类转换为泛型集合,然后赋值给接收者,如A和B ,
其中 B extends A,需要list<B> 转换为list<A>时 , 可以这样:
List list=list<b>;
List<A> receiver=list;

也可以直接
用List.class.cast()方法,如:
List<A> receiver=List.class.cast(list<B>);

86.Seekbar滑块偏上时,同时加上maxHeight和minHeight可以解决,他们是用来指定进度背景高度的。

87.AdapterView中View的状态不变化时(应用selector),和处理点击控件一样处理即可,关闭focusablity,加上FocusblockDesendants.

88.PNG使用Bitmap.compress压缩质量时会忽略quality,建议使用webp。

89.四种方式设置Activity跳转动画:http://blog.csdn.net/qq_23547831/article/details/51821159

90.XListView 需要设置Adapter才能显示Header,Footer和上下拉动

91. Dex cannot parse version 52 byte code,需要在App gradle 的android{...}中添加:

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

 


如果有Jack错误,还需要在defaultConfig{...}中添加 jackOptions { enabled true }

92.Collections.synchronizedList中所有方法都加了synchronize(mutex){...}同步,除了访问iterater的方法,需要手动加锁,请看他们的实现如下:

public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}

public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}



93.用Gradle为UMeng渠道打包首先你必须在AndroidManifest.xml中的meta-data修改以下的样子:
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}" />
然后再App的build.gradle的android{}中添加productFlavors {

YingYongBao {}
HuaWei{}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}

 


注意其中渠道名不能以数字开头。也可以使用第三方PackNG打包,不过它的渠道没有写到Manifest中,如果二次签名会导致丢失。

94.Gradle读取local.properties文件,如下读取签名配置信息

Properties properties = new Properties()
InputStream inputStream = project.rootProject.file(‘local.properties‘).newDataInputStream() ;
properties.load( inputStream )
//读取文件
def sdkDir = properties.getProperty(‘key.file‘)
storeFile file( sdkDir )
//读取字段
def key_keyAlias = properties.getProperty( ‘keyAlias‘ )
def key_keyPassword = properties.getProperty( ‘keyPassword‘ ) ;
def key_storePassword = properties.getProperty( ‘storePassword‘ ) ;
storePassword key_storePassword
keyAlias key_keyAlias
keyPassword key_keyPassword

 


95.LinearLayout比例布局时,不包含0的weight时,使用0dp才会准确。

96.出现 Bitmap too large to be uploaded into a texture错误时,是因为启用硬件加速后,无法显示较大的图片,解决方案三种:
(1)Android:hardwareAccelerated="false"关闭加速
(2)加载图片时进行压缩
(3)把大图分割成小块加载显示图片切片

 

以上是关于Android开发随手记的主要内容,如果未能解决你的问题,请参考以下文章

随手记

Java EE开发平台随手记1

随手记代码

随手记开发中遇到的问题与解决方案,持续更新...

Java EE开发平台随手记2——Mybatis扩展1

Java EE开发平台随手记6——Mybatis扩展4