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 协议 ,转载请注明出处!