1.complileSDK是编译期使用的SDK,不会打进包里,不影响运行,为了使用新特性谷歌建议选择最新的版本。minSDK决定了最低什么版本的手机可以安装,同时编译期编译期会对过高的api进行报错。targetSDK是向前兼容的核心,SDK版本升级时大多api一般会保留新旧两种代码,然后根据获取这个targetSDK来进行判断使用哪套逻辑。
Gradle文件中单引号表示只是一个单纯的字符串,双引号可以有插值操作。
2.cmake语法
生成库:addLibrary(name type source),type为STATIC生成静态库.a,SHARED生成动态库.so。在build/intermediates/cmake下。
将第三方库链接进创建的一个库,如将一个so链接进effect库:
set_target_properties(effect_shared PROPERTIES IMPORTED_LOCATION ${EFFECT_PREBUILD}/libeffect.so)
添加文件夹供编译器扫描:include_directories
添加子文件夹的CMakeLists文件参与编译:add_subdirectory(目标CMakeLists所在的文件夹,必须是子文件夹,外部文件夹可以用软连接链入作为子文件夹)。
3.在执行clone时提示目标文件夹不为空:
ls -a可以看到有一个.DB_store,删除即可。
4.接口中的成员变量默认是public static final的,这体现了接口作为一个公共的协议的本质特征。只有常量没有变量,对修改关闭,对扩展开放。
5.recyclerview执行notifyItemInserted后插入位置后面的item的position并没有加一,需要手动刷新。itemB为selected状态,在ItemB前面插入一个itemA,依次执行notifyInserted和notifyChanged(1),发现itemA为选中,因为其复用了B废弃的View。有必要在适配器中对view的选中等状态进行记录。
6.本地与远程同时有修改的情况下,git pull origin可能会产生冲突。可解决冲突后git merge —continue继续未完成的merge操作。在使用pull的时候本地修改与远程修改merge成一个新的节点,新节点有两个前驱节点,比较混乱。可以使用git pull -rebase使用rebase而不是merge,新节点只有远程修改一个前驱节点。
7.输入框自动唤起键盘的问题,除了在前面设置一个View拿到焦点外,还可以设置活动的软键盘模式: . android:windowSoftInputMode=“stateHidden|adjustResize”
8.获取一个sp对象:PreferenceManager.getDefault
9.rn读的是ReadableMap,写的是WriteableMap。bridge接收到的是ReadableMap,要转成Bundle传给rn。
10.构建变体:android{ flavorDimentions “app”,”test” productFlavors{} }
11.proguard添加一行keep后新增crash:
这一行加错了module
12.mediaplayer播放中断:局部变量不定时被系统回收,以后相关问题要考虑内存回收。
13.C++开发中不要返回一个方法体中声明的变量,使用输出参数。char*转jstring:env->NewUTFString
14.C++文件:This file is not part of the project
我先用脚本编译了工程,然后使用脚本将工程外的c++文件库链接进来。在工程目录下可以看见相应的文件了,点进去之后却显示这个This file is not part of the project,也不能调试。原来是外链进来文件后改变外部结构cmake并不会感知,所以解决方案是先clean,然后在CmakeLists文件里随便改一行后sync,然后编译运行。
而且我发现AS不能显示作为子文件夹的项目的git实时变更(左侧标注),升级3.3后没有这个问题了。
15.aty出入动画:入在最前面,出在finish后。
16.实用命令行:
查看当前activity: adb logcat | grep ActivityManager
查看库依赖关系:./gradlew :app(主module):dependencies >abc open abc
17.R爆红:因为R文件已经超过了配置的最大文件大小.. idea直接不识别这个文件了
解决方法 找到Android Studio的应用目录 修改Contents/bin/idea.properties文件中的 idea.max.intellisense.filesize 大于R文件的实际大小即可(默认2500)
比如说 idea.max.intellisense.filesize=5000 然后重启AS即可
18.bundle里的数据intent可以直接获取
Intent.putExtra实际上都是放在自己的bundle里,putExtras(Bundle b)是把b的信息都倒入bundle。Bundle里维护的是一个ArrayMap。所以getExtra也是从这个bundle取。
19.内部类会单独生成一个class文件,普通外部类持有一个外部类实例的引用,并含有一个以外部类实例作为参数的构造器,在运行时会调用这个构造器。静态内部类和普通类基本没什么不同。内部类使用的外部的变量必须是final的,因为外围变量在编译运行时实际上是赋值给一个内部变量,以后操作的都是这个内部变量,所以内部对这个变量的值改变不会传到外部。
找第三方库本地缓存:zhangyong/.gradle/caches/modules/files-2.1/
Gradle降级:gradle-wrapper.properties里改gradle-4.4-all.zip版本号
4.6那个把compiler里configure on command去掉就行了
Void作为返回类型只能返回null;Void也是一种类。
20.library中R.id不能使用switch:
从某个版本开始,library的R.id不是常量,而switch只能处理常量,在编译期写死,所以需要用if-else进行代替。
21.如果error看不出来,不妨试试debug级别下System.err过滤
22.Android studio debug卡在loaded module:boot-ext.oat
debugger模式改成java(手机原因,系统升级后不复现)
23.java
异步任务使用bolts.Task
AysncTask: 在一个进程中1.6以前在单一线程执行,1.6以后引入线程池,最多五个工作线程,超过五个任务放在缓冲队列里,缓冲队列满则开启新线程,新线程数到达系统极限报错。
cancle原理只是将cancled置为true,实际上还是需要你去手动判断,比如你写了一个循环,那么可以在每一次循环开始前判断isCancled(),或者是在异步任务结束之后进行判断来决定返回的值。
只读集合:Collections.unmodifiableList(List)
使用HandlerThread在构造器传入线程优先级有助于cpu判断任务的处理方式。
使用LoadManager可以避免内存泄漏,因为和aty/fragment的生命周期绑定。不过比较重。
String的引用赋值是新开辟了内存空间—》String是不可变的。
异常的处理:用RuntimeException包装受检异常可以抛给上一级处理,尽量让异常的语义能够明确。
asset关键字,后面跟的boolean表达式是false的时候抛出error。如okhttp中约束本方法在当前对象被其他线程加锁的时候执行出错:asset Thread.holdsLock(this);
谨慎使用String的==,只有(String s1 = “java”; String s2 = “java”;)时==返回true,这时s2的赋值用到了缓冲池中原有的string对象。
24.应用启动
可以直接在logcat中看到应用从启动到第一次绘制的时长:
类似ActivityManager: Displayed com.android.myexample/.StartupTiming: +768ms
一般来说会有一些异步加载,想要统计从应用启动到这些加载完成后的总时间则手动调用activity.onFullyDrawn,结果会在logcat打印一条和上面一样的日志。
呃,这条当时说的是啥来着。。。
25.压缩
安卓框架支持对某些目标大小格式进行压缩来获取其他格式,所以资源只需要支持mdpi,xxhdpi,xxxhdpi。其他格式可以通过这几个压缩获得。
26.UI组件
progressdialog设置为黑色背景风格:new ProgressDialog(mContext,ProgressDialog.THEME_HOLO_DARK);
27.通知
8.0引入新特性,通知必须设置渠道Id(默认的那个DEFAULT没用),否则通知不显示。将一组相似特性的通知定义为一个渠道,便于用户可以控制订阅自己想要的通知类型。Notification.Builder和NotificationCompat.Builder都可以使用。首先new NotificationChannel,然后manager.createNotificationChannel进行注册。
28.matrix应用于drawBitmap
matrix本质是通过一个3*3矩阵进行一次次乘法,在api上提供了pre,set,post,其中pre和post分别表示变换矩阵在整个变换算式的右和在左,可以感性的理解为先处理和后处理。刚开始没想到平移后再缩放得到的结果坐标点是不对的,因为缩放是相对于原点。
29.getExternalFilesDir是sd卡上的data/pkg/files,getFilesDir是内存中的。getCacheDir会在内存不足时被系统选择清理。
30.json里对象等同于Map<String,Object>
31.代码风格
(1)在Builder的构造器中为一些变量赋默认值,尽量不要有Null出现。
32.log
用一个静态常量来控制整个类的log是否打印,这样做的好处在于发版时编译期会将这些log代码全部剔除。
33.recyclerview
(1)调用延后:提供了两个方法startInterceptRequestLayout和stopInterceptRequestLayout,两个必须成对出现,在可能触发requestLayout的代码前后。前者将自定义标志位int加一,重写requestLayout判断只有标志位==1时执行super,否则将标志位boolean(是否延后执行)置为true,后者将标志位- -直到==1且标志位boolean=true时调用dispatchLayout实际执行重新布局的逻辑。这种设计保证了requesrLayout是不可重入的,去除了冗余的调用。
(2)滑动:改变子view的top和bottom