https://blog.csdn.net/huangqili1314/article/details/72792682
基础知识 – 四大组件(生命周期,使用场景,如何启动)
- 启动模式
1.Standard
2.SingleTop 栈顶复用模式
说明:分两种处理情况:须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法onNewIntent会被回调(Activity被正常创建时不会回调此方法)。
3. SingleTask 栈内复用模式
说明:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法
4. SingleInstance 单实例模式
说明: SingleInstance比較特殊,是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
java基础 – 数据结构,基本数据类型
一、Java常用数据结构:
- ArrayList:元素单个,效率高,多用于查询;
2.Vector:元素单个,线程安全,多用于查询;
3.LinkedList:元素单个,多用于插入和删除;
4.HashMap:元素成对,非同步的,并且允许null,即null value和null key; - HashTable:元素成对,线程安全,元素不可为空;
** 二、Vector、ArrayList和LinkedList**
大多数情况下,从性能上来说ArrayList最好,但是当集合内的元素需要频繁插入、删除时LinkedList会有比较好的表现,此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部,但是它们三个性能都比不上数组,另外只有Vector是线程同步的,所以:
如果能用数组的时候(元素类型固定,数组长度固定),请尽量使用数组来代替List;
如果没有频繁的删除插入操作,又不用考虑多线程问题,优先选择ArrayList;
如果在多线程条件下使用,可以考虑Vector;
如果需要频繁地删除插入,LinkedList就有了用武之地;
如果你什么都不知道,用ArrayList没错。
三、基本数据类型
1、内置八种数据类型(六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型):
byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0;
short:短整型,在内存中占16位,即2个字节,取值范围-32768~32767,默认值0;
int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0;
long:长整型,在内存中占64位,即8个字节-263~263-1,默认值0L;
float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0;
double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0;
char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空;
boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false;
2、引用数据类型:
类、接口类型、数组类型、枚举类型、注解类型。
区别:
基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
通信 – 网络连接(HttpClient,HttpUrlConnetion),Socket
数据持久化 – SQLite,SharedPreferences,ContentProvider
安全 – 数据加密,代码混淆,WebView/Js调用,https
UI– 动画
其他 – JNI,AIDL,Handler,Intent等
RxJava2+Retrofit2+OkHttp3
Retrofit:Retrofit是Square公司开发的一款针对Android 网络请求的框架(底层默认是基于OkHttp 实现)。请求的数据和请求的结果,使用接口的方式呈现。
OkHttp:也是Square公司的一款开源的网络请求库。负责请求的过程。通过OkHttpClient 可以配置很多东西,比如 链接超时时间,缓存,拦截器等。
RxJava:
a. 负责异步,各种线程之间的切换,使异步操作变得非常简单。
b. 加入RxJava后网络请求返回不再是一个call,二十一个Observable。
c. 在Activity或Fragment中传入Subscriber 建立订阅关系,就可以在onNext中处理结果了。
d. RxJava 的好处是帮我处理 线程之间的切换,我们可以在指定 订阅的在哪个线程,观察在哪个线程。
e. 可以 通过操作符 进行数据变换。
f . 整个过程都是链式的,简化逻辑。其中FlatMap 操作符 还可以解除多层嵌套的问题。
性能优化
性能分析工具
leakcanary blockcanary ddms traceview layout Inspector Analyze Inspect code
响应时间优化
1.使用优秀的网络请求框架库和数据解析框架,如retrofit、okhttp、Gson等;
2.数据缓存推荐使用三级缓存,内存缓存+本地缓存+网络请求缓存;图片有三级缓存,文件、 java内存 和 native 内存,特别针对 5.0以下系统可以用到 native 内存缓存,因为可以减少 gc 调用。
界面卡顿优化
1.避免UI主线程做耗时操作,耗时操作交给子线程完成,使用handler更新UI.
2.优化布局层级,避免过多无用嵌(如使用ConstraintLayout约束布局,扁平式的布局方式,无任何嵌套,减少布局的层级,优化渲染性能),Android通知界面渲染和重绘的时间要在16ms内完成,超出这个时间会导致丢帧。可以使用Hierarchy View进行层级分析。
内存优化
创建新的对象都需要额外的内存空间,尽量要减少创建对象。
将类,变量,方法等的权限修改为最小。
针对字符串的拼接,尽量使用StringBuffer替代String等。
不要在循环当中申明临时变量,不要在循环中捕获异常。
使用集合对象,如果事先知道其大小,则可以在构造方法中设置初始大小。
文件读取操作需要使用缓存类,及时关闭文件。
如果程序会频繁创建线程,则可以考虑使用线程池。
Recyclerview
一种插拔式的体验,高度的解耦,异常的灵活架构
- LayoutManager 控制显示方式:
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
1.LinearLayoutManager线性管理器,支持横向,纵向布局;
2.GridLayoutManager网格布局管理器;
3.StaggeredGridLayoutManager瀑布流式布局管理器;
- ItemDecoration控制Item间间隔,可以通过该方法添加分割线:
mRecyclerView.addItemDecoration()
该方法的参数为RecyclerView.ItemDecoration,该类为抽象类
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL_LIST));
- ItemAnimator控制Item增删动画;
- 但点击事件,长按事件需要自己写;
常用设计模式
单例模式
创建步骤:
a.将构造函数私有化,构造函数可避免其他程序创建该类对象。
b.在本类中创建一个私有的该类对象。
c.对外提供一个公共访问方式,为了方便其他程序访问到该类对象。
创建方式:
1.饿汉式:类一加载就创建对象
class Student{
private Student(){}
private static final Student s = new Student();
public static Student getInstance(){
return s;
}
}
2.懒汉式:使用时才创建该对象
class Student{
private Student(){}
private static final Student s = null;
public static Student getInstance(){
if(null==s) {
//线程1就进来了,线程2就进来了。
s = new Student();
}
return s;
}
}
3.饿汉式和饱汉式的区别:
饿汉式是类一加载进内存就创建好了对象;而懒汉式则是类加载进内存的时候,对象还没有存在,要使用该对象的时候再new出来;
懒汉式是延迟加载,如果多个线程同时操作懒汉式时就有可能出现线程安全问题;
为解决懒汉式的线程安全问题,解决线程安全问题可以加同步来解决。
但是加了同步之后,每一次都要比较锁,效率就变慢了,可以通过双重判断来提高程序效率。
注:开发常用饿汉式,因为饿汉式简单安全。懒汉式多线程的时候容易发生问题
Picasso,Glide,Fresco对比分析
Picasso不支持gif,
Glide,Fresco支持gif,
优点
Glide
*缓存机制
- 多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
- 生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)
- 高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
- 高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)
Fresco
- 最大的优势在于5.0以下(最低2.3)的bitmap加载。在5.0以下系统,Fresco将图片放到一个特别的内存区域(Ashmem区)
- 大大减少OOM(在更底层的Native层对OOM进行处理,图片将不再占用App的内存)
- 适用于需要高性能加载大量图片的场景
结论
- Fresco功能强大,但是对象Glide要复杂,而且需要自己的SimpleDraweeView,这一点在切换框架的时候不方便。而且Glide直接缓存ImageView相对大小的图片,节省空间的同时下场如果是同样大小的图片就不要再次请求,直接可以使用。
- Fresco虽然很强大,但是包很大,依赖很多,使用复杂,而且还要在布局使用SimpleDraweeView控件加载图片。相对而言Glide会轻好多,上手快,使用简单,配置方便,而且从加载速度和性能方面不相上下。对于一般的APP来说Glide是一个不错的选择,如果是专业的图片APP那么Fresco还是必要的。
Hybrid App中实现的主要技术native组件与js的数据交互的理解以及实现
Android WebviewJavaScriptBridge
https://blog.csdn.net/alwaysgoalong/article/details/77837405
Gradle 多渠道打包
事件分发
https://blog.csdn.net/guolin_blog/article/details/9097463