Android 实习笔记
⚠️ 杂乱无章链接且极大可能打不开
版本控制
Git 是流行的代码版本控制系统,Gerrit是代码审核系统,实现Web界面上的代码版本控制。
git checkout 撤销修改,让工作区文件回到最近一次 git commit 或 git add 时的状态
JAVA多线程访问同一个可变变量,需增加同步机制
JVM中存在一个主内存(Java Heap Memory),Java 中所有变量都储存在主内存中,对于所有线程都是共享的。
每个线程都有自己的工作内存 (Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行
线程之间无法相互直接访问,变量传递均需要通过主内存完成。
根据上述内存模型的定义,要在多个线程间安全的同步共享数据就必须使用锁机制,将某线程中更新的数据从其工作内存中刷新至主内存,并确保其他线程从主内存获取此数据更新后的值再使用
使用 System.arraycopy() 进行数组复制
在将一个数组对象复制成另外一个数组对象时,不要自己使用循环复制,可以使用JAVA提供的System.arraycopy() 功能来复制数据对象,避免出错,效率更高
.aar库文件和.jar库文件的区别
aar 文件是建立在 jar 文件的基础之上, aar 是 jar 文件的一个变种。本质上没有什么区别,都是压缩包,只是能包含的内容不一样。
- jar 只包含了 class 文件与清单文件。虽然也能包含资源文件,但不过是文本资源和图片资源,不能包含 Android 平台下的 drawable 以及各种 xml 文件.
- aar 包括的东西更多一些,包含所有资源文件、第三方库文件、so 文件、class 以及 res 资源文件全部包含。
Android接口回调机制
接口回调的意思即,注册之后并不立马执行,而在某个时机触发执行 。
回调方法就是一个通过方法指针来调用的方法(接口),如果我将这个方法的指针(地址,引用)通过形参传递到另一个类的某个方法里(setCallBack 注册),那么当这个类调用该方法里面我所传入的指针时,就能调用我这边的方法。
整个过程就是我传入方法 A 的地址,你接收,并在某个时刻回调我这边的 A 方法。由于 Java 没办法操作指针,于是它用接口来实现。
主要步骤如下:
- 定义接口 Callback ,包含回调方法 callback();
- B 类提供注册的方法,并设定在某个条件下会回调接口方法;
- A 类提供接口的实现方法,并注册到 B 类,把方法地址传进去。
这样,在需要的时候,可用 CamCallback 接口成员调用 callback() 方法,完成回调了。
例子:
1 | |
另外的网页参考:
http://www.apkbus.com/thread-589290-1-1.html
https://www.jianshu.com/p/f05730ab5d05
EditText 不换行
1 | |
Java 中 int 转 String 的三种方式
- a+”“ 这种效率最低
- String.valueOf(a)
- Integer.toString(a)
牛逼的 material-dialogs
https://github.com/afollestad/material-dialogs
解决支持库版本兼容问题
如果引用的第三方库的支持库版本低于(或者不一致)app build.gradle 中的支持库版本,可能会出现如下问题:
all com.android.support libraries must use the exact same version specification(mixing versions can lead to runtime crashes)
去改第三方库所用的支持库版本比较麻烦,如果用的库很多的话工作量很大。这个时候我们可以考虑强制让所有模块都用相同的支持库版本。
在 app build.gradle 中添加:
1 | |
TextView滚动设置
只要在布局的 xml 文件中设置 TextView 的属性:
1 | |
然后在代码中用:
1 | |
它可以自由的滚动了。
Android 文件下载三种基本方式
1.自己封装 URLConnection 连接请求类
这种方式在 Android 刚兴起的时候,很少下载封装框架,就自己封装了。虽然一般的文件都能下载,但这种方式缺点很多,不稳定或者各种各样的问题会出现。
2.Android 自定的下载管理(会在 notification 显示下载的进度,同时可以暂停、重新连接等)
这种方式其实就是交给了 Android 系统的另一个 app 去下载管理。这样的好处不会消耗该APP 的 CPU 资源。缺点是:控制起来很不灵活。
https://www.jianshu.com/p/46fd1c253701
https://www.cnblogs.com/gooder2-android/p/8966045.html
3.使用第三方 okhttp 网络请求框架
okhttp 是一个很有名气的开源框架,目前已经很多大公司都直接使用它作为网络请求库(七牛云 SDK, 阿里云 SDK)。 且里面集成了很多优势,包括 okio (一个 I/O 框架,优化内存与 CPU)。
综合来看,第三种方案是最佳的,是目前最流行的下载方案。
第三方框架还研究了封装 okhttp 的OKgo
Android 6.0 以上文件读写权限
除了在清单文件中声明权限,还需要在访问文件时动态申请权限
1、AndroidManifest.xml 文件添加:
1 | |
2、onCreate() 或其他访问文件位置添加授权
1 | |
没有第二步的话需要自己去手机的应用程序设置手动允许权限。
Android 7.0 FileProvider 问题
https://blog.csdn.net/growing_tree/article/details/71190741
lambda 表达式
Java的新特性,目的是使得代码更加简洁,只有一个待实现方法的接口,都可以使用 Lambda表达式的写法,例如
1 | |
转成 Lanbda 表达式就是
1 | |
如需为您的项目启用 Java 8 语言功能和 Jack,请在模块层级的 build.gradle 文件中输入以下内容:
1 | |
Jsoup 安卓端的爬虫
加库后用三行代码,即可获得应用名到应用包名的转换。感谢酷安
1 | |
解决网络请求多线程的骚操作
问题是:如何让主线程等待子线程获得网络数据后再继续运行?
设网络数据为全局变量 x,再设一个全局 flag 变量。设全局变量是为了让变量可访问,但不知会否引起安全和效率问题。
主线程设置 flag 变量的死循环,子线程执行网络请求,成功修改 x 完毕再修改 flag 变量,使得主线程离开死循环继续执行。这时,主线程就能使用到存储了网络数据的 x 变量。(机智)
https://bbs.csdn.net/topics/391838191
AsyncTask 优点缺点
优点:简单快捷
缺点:后台真正只有一个线程,多线程是串行执行的
https://blog.csdn.net/evan123mg/article/details/52960339
Handler学习
https://blog.csdn.net/u010177022/article/details/63278070
https://blog.csdn.net/songmingzhan/article/details/78408383
https://www.cnblogs.com/ryanleee/p/8204450.html
https://www.cnblogs.com/android007/archive/2012/05/10/2494766.html
避免内存泄漏
https://www.cnblogs.com/JohnTsai/p/5259869.html
主线程给子线程传参数
https://blog.csdn.net/choubaoguai/article/details/23671441
构造函数传递数据
定义一个线程类,扩展 Thread,增加一个成员变量,用来保存传进来的参数。新加一个拷贝构造函数,拷贝写入到成员变量。
变量和方法传递数据
回调函数
ADB 快捷从电脑安装apk到手机
打开 cmd,输入指令,路径可以直接从资源管理器拖过去
1 | |
注解:编译时注解和运行时注解
http://www.mamicode.com/info-detail-1317919.html
http://www.importnew.com/1796.html
动态权限申请
https://github.com/mylhyl/AndroidAcp
Android 存储路径
补充:对于现在市面上很多 Android 设备,自带了一个大的存储空间,一般是 8GB 或 16GB,并且又支持了 sdCard 扩展,对于这样的设备,使用 Enviroment.getExternalStorageDirectory() 方法只能获取到设备自带的存储空间,对于另外扩展的 sdCard 而言,需要修改路径。
保存到应用的内部文件夹——在 “Android/Data/应用包名/…”路径下,卸载应用时也会一并清除
通过 getExternalFilesDir() 方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据
通过 getExternalCacheDir() 方法可以获取到 SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
应用外部的话,可以用 Environment.getExternalStorageDirectory() 来索取到默认内置存储的根路径,即 “/storage/emulated/0”,这种情况下卸载应用时不会清除哦
Handler 理解源码分析
https://blog.csdn.net/lishuangling21/article/details/70767586
获取 Android 手机里所有已安装的APP
https://blog.csdn.net/lishuangling21/article/details/50789715
Eclipse copy 风格的快捷键
ctrl+H 找有没有引用
ctrl+shift+R 进入文件的资源管理器路径
项目恢复
资源管理器中右键模块→ GIT → Revert →找到相应的模块项目恢复即可
工程资源清理
https://blog.csdn.net/caoxiao90/article/details/51057986
打开 AS,点击工具栏的 Analyze-Run Inspection by Name-输入 unused resources-选择要搜索的范围回车-查看搜索结果并删除无用的资源文件
出来运行结果后,展开到最小条目后,双击打开文件,再在资源管理器右上方点击多重圆圈按钮 “Scroll from source”,定位到具体文件夹,注意最好要在 Android 视图方式打开,可以合并同类资源到同一个文件夹下面,然后直接删除文件夹可以一次性删除多个。删除时要选中 Safe search,会进行再次检查有没有 usage,最后才确认是否删除
在 Version Control 中可以找到改动,便于检查
确保效果和不出差错,善于利用 ctrl+H 找有没有引用和 ctrl+shift+R 进入文件的资源管理器路径
【Android 珍藏】推荐10个炫酷的开源库
https://juejin.im/post/5b50898ef265da0fa21a7f0f
ButterKnife@BindView 时报 Required view ID was not found 异常
解决思路:在 @BindView 前面加上 @Nullable 或者 @Optional
BottomNavigationView 的相关网页
https://blog.csdn.net/yihuangol/article/details/74370289
https://blog.csdn.net/xiaoyangsavvy/article/details/70213537
Fragment 使用
https://www.jianshu.com/p/fd71d65f0ec6
开发要点
所有变量声明放在最外面,初始化看情况而定,List,arrarylist 这些可以声明时就初始化,直接 new…
Butterknife 和 reclclerview 的综合用法
https://www.aliyun.com/jiaocheng/15082.html
RecyclerView 点击事件接口回调
https://blog.csdn.net/willba/article/details/72878345
https://blog.csdn.net/weikai_/article/details/78936013
https://blog.csdn.net/xieluoxixi/article/details/61924372
https://blog.csdn.net/dl10210950/article/details/52918019
获取 RecyclerView 的 Item 中的 EditText 的内容
1 | |
透明背景文字图片做法
利用ppt,确定文字效果以后再复制,左上角找到选择性粘贴,选中 “PNG图片”,图片粘贴在PPT上面后再另存为图片保存为 PNG 格式,保存到资源文件管理器中
RecyclerView 复用问题,坑大半天的问题
onBindViewHolder 会有多次调用重绘,if-else 条件必须确保完整。
1 | |
https://blog.csdn.net/csdn_aiyang/article/details/80094302
https://blog.csdn.net/like_program/article/details/52517119
SwipeRefreshLayout 使用
https://www.jianshu.com/p/d23b42b6360b
https://blog.csdn.net/yl104221034/article/details/50582644
ImageButton 背景透明
xml里面设置 android:background=”@null”
坑爹 RecyclerView 获取子 Item 位置问题
getChildAt 函数只能获取屏幕可见的子 Item
https://blog.csdn.net/binbin960211892/article/details/78662388
https://blog.csdn.net/higson/article/details/52819327
跳转应用市场详情界面查看
https://www.jianshu.com/p/a4a806567368
文件搜索
https://blog.csdn.net/qq_21194621/article/details/51627274
https://blog.csdn.net/zzh12138/article/details/71077909
https://blog.csdn.net/sinat_33585352/article/details/80741648
计算 App 占用空间
https://blog.csdn.net/bingqingsuimeng/article/details/51062300
https://blog.csdn.net/m6711154/article/details/52000041
避免代码复用出现问题
setVisibility 为不可见之后要注意判断后面还有没有复用,添加 if 判断重新设置为可见
文件扫描搜索
https://blog.csdn.net/yuzhiqiang_1993/article/details/78140580
通过媒体库提供方式实现文件扫描搜索
https://www.jianshu.com/p/a6bdbefde77a
https://blog.csdn.net/zocki33250/article/details/48112669
https://blog.csdn.net/yaochangliang159/article/details/51878841
RecyclerView 完美实现拖拽,滑动删除,撤销删除
https://blog.csdn.net/hymanme/article/details/50931082
SurfaceView 用处,用法
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1201/656.html
https://blog.csdn.net/ShanYu1198124123/article/details/52448586
SurfaceView 和 TextureView 对比
https://blog.csdn.net/hejjunlin/article/details/58582919
我的思路是用 MediaPlayer 和 TextureView 来结合实现。(VideoView底层用的也是MediaPlayer,至于为什么不用 SurfaceView 而用 TextureView,是因为 SurfaceView不能放在可滑动的控件中,至于具体原因和缺点如果不清楚可自行百度之,TextureView 正是为了解决这个问题而存在的。
在 Android 总播放视频可以直接使用VideoView,VideoView是通过继承自SurfaceView来实现的。SurfaceView的大概原理就是在现有View的位置上创建一个新的Window,内容的显示和渲染都在新的Window中。这使得SurfaceView的绘制和刷新可以在单独的线程中进行,从而大大提高效率。但是呢,由于SurfaceView的内容没有显示在View中而是显示在新建的Window中, 使得SurfaceView的显示不受View的属性控制,不能进行平移,缩放等变换,也不能放在其它RecyclerView或ScrollView中,一些View中的特性也无法使用。
Mediaplayer换成Exoplayer的方法
版本号 2.5版本以前为 r2.x.x,2.5版本以后为 2.x.x
了解两种播放器的状态转换和监听接口回调,多打日志观察回调过程。
学习接口的写法,就像这次项目的更换,在有 Mediaplayer 的地方换成 ExoPlayer 的对应方法即可。VideoPlayerController 的代码完全不用改。
新优化集成问题
第一时间想到能否集成,集成开销,对 APK 包大小的影响,老机器版本兼容性,建立表格,拍摄小视频等确认效果对比。
开源项目推荐的网址
https://www.ctolib.com/android/
“==” 和 “equals” 有什么差别?
equals用于判断对象的内容是否相等,==运算符用于比较对象的引用是否一致
Apk 反编译
https://blog.csdn.net/s13383754499/article/details/78914592
https://www.cnblogs.com/spring87/p/4525647.html
依赖源码不起作用?三大重置方法
- clean project
- Invalie Cache and restart
- 关掉instant run
CMD Markdown编辑器
https://www.zybuluo.com/mdeditor
So 文件兼容 CPU 架构
http://xuchongyang.com/2017/03/12/%E6%8E%A2%E5%AF%BB-Android-so-%E5%BA%93/
Binary XML file line # : Error inflating class
https://blog.csdn.net/huangxiaohu_coder/article/details/8497286
https://blog.csdn.net/xiabing082/article/details/43487159
Complie 和 Provided 区别
Provided只是IDE编译时依赖,但是不打包到APK,也就是说编译时通过,但是不保证手机安装APK后是否能运行。
TextView 优化
http://codethink.me/2015/04/23/improving-comment-rendering-on-android/
视频基础知识
https://blog.csdn.net/zhs4430169/article/details/76502217
Android 性能优化
https://www.jianshu.com/p/307ba8911799
DNS 优化
https://my.oschina.net/sudujuncom/blog/874699
修改第三方库
final 类型的不可继承修改
继承要修改的类,右键新类名可以 generate 构造函数。再 @Override 具体修改的函数,记得要 super 父类函数
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!