Android 随心笔记(更新至2021.07.05)
Posted 小柴的回忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 随心笔记(更新至2021.07.05)相关的知识,希望对你有一定的参考价值。
笔记
小柴的笔记
笔记都是零碎的笔记,请先在右边目录查看是否有自己需要的内容,也可以向笔者提供自己觉得重要,觉得好的笔记。谢谢观看
面向对象的三大特征
- 多态
- 封装
- 继承
面向对象的五大基本原则
- 单一职责原则
- 开放封闭原则
- 里氏替换原则
- 接口隔离原则
- 依赖倒置原则
Activity的生命周期
生命周期有7个,分别是:
onCreate()、onStart()、onResume()、onPause、onStop()、onDestory()
启动Activity:onCreate() → onStart() → onResume() → 点击home键退出Activity →onPause() → onStop() 再重新进入Activity → onRestart() → onStart() → onResmue()
启动Activity:
FirstActivity:onCreate() →
FirstActivity:onStart() →
FirstActivity:onResume() →
FirstActivity:onPause() →
切换第二个Activity →
SecondActivity:onCreate() →
SecondActivity:onStart() →
SecondActivity:onResume() →
SecondActivity:onPause() →
返回第一个Activity →
FirstActivity:onRestart() →
FirstActivity:onStart() →
FirstActivity:onResmue() →
SecondActivity:onStop() →
SecondActivity: onDestory()
Activity启动模式
- standard 默认模式:每创建一个Activity都回向栈中加入一个Activity
- singleTop 栈顶模式:只要栈顶的Activity是我们需要创建的Activity,那就会直接复用栈顶的Activity使用
- singleTask 栈中复用模式:只要栈中存在Activity是我们需要创建的Activity,将上面的Activity弹出,并那就将该Activity置顶.
- singleInstance 单例模式:创建一个新的栈(Task),只用于存放该Activity
android 常用的设计模式
- 单例模式
- 建造者模式(Build模式)
- 观察者模式 (EventBus为观察者模式)
- 适配器模式
- 代理模式
- 工厂模式
- 策略者模式
单例模式
确保某一个类的实例对象只有一个,且此类的实例对象供整个程序使用。这是笔者任务较好的单例模式
public class Test{
private static Test instance = null;
private Context mContext;
//构造函数
private Test(Context context){
mContext = context
}
/**
* 为何要两次判断呢,因为如果只有第一次的话,可能会出现多个线程同时调用方法,
* 导致同时创建多个单例实例。而只有第二次的话,创建之后每次使用单例都得多线程等待,导致浪费时间。
* 所以,当多个线程同时调用,但却没有单例时,排队一个一个进入线程同步,这样第一个进入时没单例,
* 就创建单例,第二个进入的时候,判断已经有单例,就创建单例。
*/
public static Test newInstance(Context context){
context = context.getApplicationContext();
if(instance == null){ //先判断是否存在单例
synchronized(Test.class){//存在单例的时候,在通过同步锁锁住
if(instance == null){//进入同步锁后,再次判断是否存在单例,不存在就新建单例
instance = new Test(context);
}
}
}
return instance;
}
}
建造者模式(Build模式)
将一个复杂对象的构造与表示分离,使同样的构建过程可以创建不同的表示
而最经典的建造者模式的使用就是我们经常使用的Dialog对话框
使用builder内部类对象的.setIcon方法设置图标,setTitle方法设置标题等等,最后使用.create()方法创建一个AlerDialog对象,通过AlerDialog.show方法显示对话框
public void setDialog(){
AlertDialog.Builder builder= new AlertDialog.Builder(this);
AlertDialog dialog = builder
.setIcon(R.drawable.chai)//我是图标
.setTitle("我是标题")
.setMessage("我是提示信息")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, "你选择了确定", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, "你选择了取消", Toast.LENGTH_SHORT).show();
}
})
.create();
dialog.show();
}
匿名类
接口是不能被new实例化的,所以我要在内部重写需要的接口方法,这样就可以new出一个实现接口方法的对象,但因为这个对象的类名不可见,所以被叫做匿名类
//比如Service的的IBinder接口
IBinder mIBinder = new IBinder(){
//重写的方法
};
handler的使用,主线程向子线程发送信息
不能立即发送mHandler,因为handler在子线程创建实例,主线程运行发送信息的时候,他不一定创建完成。
private Handler mHandler;
new Thread(new Runnable(){
@Override
public void run(){
Looper.prepare();
mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg){
super.handleMessage(msg);
switch(msg.what){
case 0x02:
Log.d("Memory", "0x01:" + msg.arg1);
}
}
};
Looper.loop();
}
}).start();
//不能立即发送mHandler,因为handler在子线程创建实例,主线程运行发送信息的时候,他不一定创建完成。
Message msg = Message.obtaion();
msg.what = 0x02;
msg.arg1 = 123456;
mHandler.sendMessage(msg);
ANR
ANR是应用无响应的
在主线程超过5秒、广播超过10秒、服务超过20秒
后台广播超过60秒、后台服务超过200秒、内容提供者超过10秒
的延时操作时,应用就会报ANR应用无响应
处理方法很明确,不要做超过规定时间的延时操作
具体方法如下
- UI线程尽量只做更新UI的事
- 使用子线程处理IO操作、数据库操作、连接网络等有可能延时的操作
- 若广播需要做延时操作,在IntentService线程进行延时操作
泛型类与泛型方法
- 泛型类是在实例化类的时候指明泛型的具体类型
- 泛型方法是在调用方法的时候指明泛型的具体类型
- 泛型方法在泛型类中有以下两种情况:
- 泛型方法的泛型T 是一个全新的泛型 和类中的泛型T可以是相同类型,也可以是不同的任意类型
- 泛型方法的泛型A和类中的泛型A 可以是相同类型,也可以是不同的任意类型,即便没有在类中生声明,也能正常识别
class MyClass<T> {
public <T> void method1(T t){
...
}
public <A> void method2(A a){
...
}
}
可变参数
意思就是运行定义多个参数。
如下的属性动画ValueAnimator的源码,参数就是可变参数,可以多个int值
public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
ValueAnimator valueAnimator = ValueAnimator.ofInt(10,100,10,100,10,100,10);
ValueAnimator valueAnimator = ValueAnimator.ofInt(10,100,50,30);
RecyclerView、ViewHolder、Adapter的关系
- RecyclerView的工作是回收和定位屏幕上的View
- ViewHolder的工作是容纳View视图
- Adapter用于创建必要的ViewHolder,绑定ViewHolder至模型层数据
RecyclerView需要视图对象的时候,会去找Adapter,Adapter返回数据给RecyclerView
Android系统架构(五层)
- 应用层
- 应用框架层
- 系统运行库层
- 硬件抽象层
- Linux内核层
应用层
系统内置的应用程序以及非系统级的应用程序都属于应用层。负责与用户进行直接交互。有Java、Kotlin、Flutter三种开发方式。
应用框架层
应用框架层为开发人员提供了可以开发应用所需要的API,我们平常开发应用程序都是调用这一层所提供的API开发,也包括系统的应用。
使用Java编写,被称为Java Framework
系统运行库层
又分为两个库:C/C++程序库和Android运行时库
硬件抽象层
位于操作系统内核与硬件电路之间的接口层,硬件抽象化,保护硬件厂商的知识产权,隐藏特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可以再多种平台上进行移植。简单来说:就是将控制硬件的动作存放在硬件抽象层
Linux内核层
Android的核心系统服务基于Linux内核,在此基础上添加了部分Android专用的驱动。系统的安全性、内存管理、进程管理、网络协议栈和驱动模型等都依赖于该内核。
Android系统启动流程
- 启动电源以及系统启动,引导程序Bootloader,Linux内核启动
- 启动init进程(第一个进程)
创建一些文件夹并挂载设备
初始化和启动属性服务
解析init.rc配置文件并启动zygote进程
- 启动zygote进程
创建AppRuntime并调用其start方法,启动Zygote进程。
创建DVM并为DVM注册JNI
通过JNI调用ZygoteLnit的main函数进入Zygote的Java框架层
通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用进程
启动SystemService进程
- 启动SystemService进程
启动Binder线程池,用于和其他进程通信
创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理
启动各种系统服务
- 启动Launcher 应用程序
启动SystemService进程后,会启动PackageManagerService,PackageManagerService启动后将系统种的应用安装完成。在此前以及启动ActivityManagerService会启动Launcher
ActivityManagerService的systemReady()函数启动Launcher
启动Launcher后将已安装的应用的快捷图标显示到界面上
AMS的启动流程
AMS的启动是再SystemService进程种启动的
- 通过SystemService的main()函数中调用SystemService().run()函数
- 通过SystemService.run()函数中的startBootstrapServices()函数中调用的(AMS属于引导服务)
- 调用mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();//1获取AMS - 在startService()中通过反射来创建Lifecycle的实例,同时得到Lifecycle的构造器constructor,
- 在startService()中 service = constructor.newInstance(mContext) 来创建Lifecycle类型的service对象。
- 将创建的service添加到mService对象列表中注册
- service.onStart()启动service
- 在创建Lifecycle对象时,它的构造方法中已经创建了AMS对象 AcitivitManagerService mService = new ActivityManagerService(context)
- Lifecycle的onStart()里面就是 mService.start() 启动AMS
- Lifecycle的getService()里面就是 return mService 返回AMS
(所以第三条的startService传入的时Lifecycle.class,最后getService()获取AMS)
AMS的作用
AMS是系统核心服务,主要用于处理系统中四大组件的启动、切换、调度以及应用进程的管理和调度等工作
AMS 和 AM的关系
ActivityManager,主要用于对运行中的Activity进行管理,但管理工作是由AMS处理的。
因为AMS作为系统核心服务,不能暴露很多API给ActivityManager。
所以ActivityManager通过ActivityManagerNative(AMN)类的getDefault方法获取ActivityManagerProxy(AMP),然后通过AMP,和AMN通信,又因为AMS是AMN抽象类的子类,所以ActivityManger可以通过AMP和AMS通信
PMS
包是指将Apk、jar、so文件等加载到Android内存中
由一个包转变成可执行的代码。需要包管理机制来进行包的加载、解析、管理等操作
PackageManager的主要功能
- 获取一个应用程序的所有信息
- 获取四大组件的信息
- 查询permission相关信息
- 获取包的信息
- 安装、卸载APK
PackageInstaller
- 用于安装、卸载和更新应用程序
- 根据Uri不同的Scheme协议不同,进行不同的隐式跳转,content协议就跳转到InstallStart,其他就跳转到PackageInstallerActivity
- InstallStart主要的作用是将"file://Uri"转换成"content://Uri",就可以进入到PackageInstallerActivity
- PackageInstallerActivity会对package协议和file协议的Uri进行处理,如果是file协议会解析APK文件得到包信息PackageInfo
- PackageInstallerActivity会对未知来源进行处理,如果允许安装未知来源或者APK不是未知来源,则会初始化安装确认界面,如果限制的未知来源,则通过Dialog或跳转到设置页面来处理。
- 点击确认安装后,将APK的信息通过IO流的形式写入到PackageInstaller.Session中
- 调用PackageInstaller.Session的commit方法,将APK的信息交由PMS处理
以上是关于Android 随心笔记(更新至2021.07.05)的主要内容,如果未能解决你的问题,请参考以下文章