android 简述
Android 开源,基于Linux的移动设备 **操作系统**。
Android应用程序 Android软件开发工具包 Android应用程序打包
API级别: 用于唯一标识API框架版本的整数
Android环境搭建
java Jdk
Android SDK
JRE
Android Studio
Android架构
五个部分 和 四个主要层
一个应用程序应该包含哪些东西? 界面 + 通知 +资源 +内容 +活动?
1. Applications 层
------------------------
2. Application Framework 层
应用层框架以java类的形式为应用程序提供许多高级的服务
1. 活动管理者(activity manager) --控制应用程序生命周期和活动栈的所有方面
2. 内容提供者 --允许应用程序之间发布和分享数据
3. 资源管理器 -- 提供对非代码嵌入资源的访问,如字符串,颜色设置和用户界面布局
4. 通知管理器 -- 允许应用程序显示对话框或者通知用户
5. 视图系统 -- 一个可扩展的视图集合,用于创建应用程序用户界面
-------------------------
3. Libraries 层 Android Runtime
程序库的集合,包括开源的Web浏览器引擎Webkit,知名libc库,Sqllite,用于播放,录制音频的库,用于网络安全的SSL库等,与底层系统交互???
Android开发基于等Java程序库
1. android.app
2. android.content
3. android.database
4. android.opengl
5. android.os
6. android.test 设备上显示和渲染文本
7. android.view 应用程序用户界面等基础构建模块
8. android.widget 丰富的预置用户界面组件集合,包括按钮,标签,列表,布局管理,单选按钮。。。
9. android.webkit
安卓运行时:
Dalvik虚拟机的关键组件,类似于java的虚拟机,使得可以在java中使用Linux核心功能,如内存管理和多线程
Dalvik虚拟机使得每一个Android应用程序运行在自己独立的虚拟进程
-------------------------
4. Linux kernel 层 (底层系统,比如要调用声音,摄像头。。。。)
提供了基本的系统功能,比如进程管理,内存管理,设备管理(摄像头,键盘,显示器等),如网络和大量的设备驱动,避免兼容大量的外围硬件接口带来的不便
安卓应用程序组件
应用程序组件是一个Android应用程序的基本构建块(应用程序是由不通的组件组成???)
清单文件松耦合组成, AndroidManifest.xml描述了应用程序的每个组件,以及他们如何交互
四个主要组件:
Activities 描述UI层,并且处理用户与机器屏幕的交互
Services 处理与应用程序关联的后台操作
Broadcast Receivers 处理android操作系统和应用程序之间的通信
Content Providers。 处理数据和数据库管理方面的问题
Activities
一个activity标识一个具有用户界面的单一屏幕,当应用程序多于一个活动,其中的一个会被标记为 当应用程序启动的时候显示
public class MainActivity extend activity{
}
Activity是啥呢
Activity是一个应用组件,用户可与其提供的屏幕进行交互
每个activity都会获得一个用于绘制其用户界面的窗口,可充满屏幕也可以不
主activity(启动时加载的activity) + 其他松散的activity。每个activity均可以启动另一个activity,以便执行不同的操作
Activity manager (windows manager) 管理activity
activity栈
- 生命周期:
onCreate() : 此方法需调用setContentView(),定义Activity用户界面布局
Activity的用户界面是由层级式视图-衍生自VIEW类的对象提供的
启动Activity
startActivity()
应用自身可能不具有执行某类操作所需的activity,只能利用设备上其他应用进行响应——Intent对象真正意义所在。
启动activity以获得结果
startActivityForResult()
onActivityResult()。——》完成activity启动,使用Intent向onActivityResult()方法返回结果
** 4. 结束Activity **
finish() finishActivity()结束您之前启动的另一个activity,但最好不用显示调用
- 可见生命周期
onStart() onStop()之间,在onStart()中注册一个BroadcastReceiver以监控影响UI的变化,在onStop中取消注册, 可见和隐藏状态中切换数据传递
- onPause()
在此回调方法中向存储设备写入至关重要的持久性数据(如用户输入),但此过程会妨碍向下一个activity的转变,影响用户体验
- 如何保存activity的状态
当activity暂停或者停止时,activity的状态会得到保留(保留在内存中,如果没有被系统干掉)
onSaveInstanceState(Bundle) ——》以确保有关的activity状态的重要信息保留
使用putString() 和 putInt()等键值对形式保存有关Activity状态信息
将Bundle同时传递给onCreate()和onRestoreInstanceState()
**默认实现会为布局中的每个VIew调用相应的onSaveInstateState()
- 适应屏幕尺寸
Services
服务是运行在后台的,执行长时间的组件???。 服务可以是用户在使用不同的程序时在后台播放音乐,或者在活动中通过网络获取数据但不阻塞用户交互
public class MyService extends Service{
}
Broadcast Receivers
广播接收器 响应从其他应用程序或者系统发来的广播消息,应用程序可以发起广播让其他应用程序知道一些数据已经被下载到设备,并且供他们使用。因此广播接收器会拦截这些通信并采取适当的行动
public class MyReceiver extends BroadcastReceiver{
}
Content Providers
通过请求一个应用程序到另一个应用程序提供数据 ,这些数据可以是存储在文件系统,数据库或者其他地方
public class MyContentProvide extends ContentProvider{
}
附件组件
Fragments 代表活动中的一个行为或者一部分用户界面
Views 绘制在屏幕上的UI元素 包括按钮 列表等
Layouts。控制屏幕格式 展示视图外观的View的继承
Intents。组件间的消息连线
Resources 外部元素,例如字符串资源 常量资源 以及图片资源
Manifest 应用程序的配置文件,这个文件是Android操作系统与你的应用程序之间的接口,因此,如果没有在这个文件中声明你的组件,将无法被操作系统识别
安卓应用程序目录结构
res/values
strings.xml 包含应用程序使用到的所有文本
XXX
R 文件 gen/com.example.helloworld/R.java 如MainActivity.java和资源如strings.xml的胶水,这是一个自动生成的文件,不要修改
activity_main.xml是一个在res/layout目录下的layout文件。**当应用程序构建它的界面时被引用**,修改此文件来修改应用程序的布局
Android资源(Resources)访问
静态内容:位图,颜色 布局定义 用户界面字符串 动画。。。这些资源一般放在res/独立子目录中
res/
drawable/
icon.png
layout/
定义用户界面布局的XML文件
activity_main.xml
values/
strings.xml
anim/
定义动画属性的xml文件。通过R.anim访问
color/
定义状态列表的xml文件
drawable/
图片文件
menu/
定义应用程序菜单的XML文件,如选项菜单,上下文菜单 子菜单
raw/
任意文件以他们的原始形式保存
xml/
可以通过调用Resources.getXML()在运行时读取任意文件的XML文件。
替代资源
应用程序需要为特定的设备配置提供替代的资源支持,在运行时,Android检测当前设备配置,并为应用程序加载合适的资源
访问资源
当Android应用程序被编译,生成一个R类,其中包含了所有res/目录下的资源ID,可以使用R类,通过子类+资源名或者直接使用资源ID来访问资源
Activity
activity 代表了一个具有用户界面的单一屏幕,如Java的窗口或者帧 是ContextThemeWrapper类的子类
安卓系统的初始化是通过activity中的on create()回调的调用开始的,
存在一系列的回调方法来启动一个活动
同时有一系列的方法来关闭活动
activity的生命周期
activity launched ---》-----〉---》-----〉---》activity shutdown
Service
service是一个后台运行的组件,执行长时间运行且不需要用户交互的任务,即是应用被销毁也依然可以工作
1. Started 如activity通过startServices()启动了服务,则服务是started状态,一旦启动,服务可以在后台无限期运行,即是启动它的组件被销毁
2. Bound 通过bindService()绑定了服务。 Bound状态的服务提供了一个客户服务器接口来允许组件与服务交互,如发送请求,获取结果。。。
服务的生命周期。。。。。
BroadcastReceivers
用于响应来自其他应用程序或者系统的广播消息
1. 创建广播接收器
2. 注册广播接收器:应用程序通过在manifest.xml文件中注册广播接收器来监听制定的广播意图
Android 内容提供者(content provider)
通过请求一个应用程序向其他的应用程序提供数据 ContentResolver类,内容提供者可以使用不同的方式来存储数据
内容URI: :////
prefix :前缀 一直被设置为content://
authority: 授权 制定内容提供者的名称
data_type:数据类型
content://contacts/people
id: 指定特定的请求记录
content://contacts/people/5
创建内容提供者:
首先,继承类 ContentProvidersbase 创建一个内容提供者类
其次,需要定义用于访问内容的 你的内容提供者的uri地址
接着,创建数据库保存内容
最后, 使用 在AndroidManifest.XML中注册内容提供者
Android 碎片(Fragment)
Fragment 是activity的一部分是更加模块化的设计,可以认为是一个子activity
重要知识点:
1. 拥有自己的布局,自己的行为以及自己的生命周期回调
2. 当activity在运行的时候,可以在activity中添加或者移除碎片
3. 可以合并多个Fragment在一个单一的activity构建多栏的ui
4. fragment可以被用在多个活动中
5. fragment的生命周期和它的宿主activity紧密关联,意味着activity被暂停,所有activity的fragment都被停止
6. fragment可以实现行为而没有用户界面组件
7. fragment是android api 11 加入的
通过继承Fragment类创建碎片
可以有一个单一的activity,但每个activity由多个fragment组成,每个fragment有自己的layout,事件和完整的生命周期
fragment的生命周期
如何使用fragment
1. 首先决定在activity使用多少个fragment,比如使用两个fragment来处理横屏和竖屏的两种模式
2. 基于fragment的数量,创建继承自Fragment的类
3. 对应每个fragment,需要在XML文件中创建布局
4. 最后基于需求修改activity文件来定义实际的fragment替代逻辑
基础整理 MS
四大组件:activity service content provider broadcast recevier
什么是activity:
1. 一个activity通常就是一个单独的屏幕(窗口)
2. activity之间通过**intent**进行通信
3. android应用中每一个activity都必须再**AndroidManifest.xml**配置文件中声明,否则系统不识别也不 执行该activity
什么是service:
1. service用于在后台完成用户的指定操作,service分两种:
1.1 start(启动) ,当应用程序组件(如activity)调用startService()方法启动
1.2 bound(绑定),当应用程序组件调用bindService方法绑定到服务,服务处于bound
2. started service() 与 bindService的区别 都能启动服务
3. 应当在应用程序**配置文件**中声明全部的service
4. Service通常位于后台运行,一般不需要与用户jiaohu
安卓主线程和子线程
Android线程 : 主线程 子线程
1. 主线程-->(UI事件+后台服务)也为UI主线程:主要作用就是运行四个组件,处理交互界面
ActivityThread为应用程序的主线程类,所有apk程序都有且仅有一个ActivityThread类
2. 子线程-->,创建多个子线程处理后台服务,比如处理耗时任务,网络请求,I/O操作
子线程为什么不能更新UI:
UI访问没有加锁,访问UI不安全
SurfaceView是android唯一一个可以在子线程更新的控件,避免画图任务的繁重
系统本身是无法区分当前线程到底是主线程还是子线程
子线程和主线程通信机制
可以用handler
java线程概念:
1. Thread Runnable
2. Callable Future
3. 线程池 ThreadPoolExecutor
线程复用,避免大量创建,销毁线程带来的性能开销
可控制线程的最大并发数,避免线程之间抢占资源造成阻塞
4. IntentService HandlerThread
5. AsyncTask
**IntentService HandlerService**
1. IntentService是android中特殊的service,可用于执行后台耗时任务
onHandlerIntent(){}
系统会底层干预,干掉某些东西 保证用户体验
为什么会出现ANR?
Android希望UI线程能够根据用户的要求快速做出响应,如果UI线程太花时间处理后台工作
UI事件发生时,让用户等待5s而不做处理,**Android系统**就会给用户显示ANR提示
原因是BroadcastReceiver的onReceive()函数运行在主线程中,在特定的时间(10秒)内无法完成处理。
/data/anr/traces.txt
常见目录
Android系统/proc目录详解
/proc/cmdline:显示内核启动的命令行。
/proc/meminfo:显示物理及虚拟内存使用情况。
/proc/cpuinfo:显示系统cpu的信息。
Proc/mounts:当前系统所安装的文件系统信息(包括手动安装的)
AccessibilityService
无障碍辅助服务,致力于帮助15%的生理不方便人士以及某个场景下无法用手的用户
AccessbilityService运行在后台,监听事件AccessbilityEvent(焦点改变,输入内容变化,按钮被点击等等)
该服务能够请求获取当前活动窗口并查找其中的内容
任何变化都会产生一个时间,并由系统通知给AccessbilityService
Accessibility:无障碍,又称辅助性功能.
AccessibilityService:无障碍服务,继承于 Serveice. 它可以监听操作、检索窗口内容、启用触摸浏览等
- 手机如何开启无障碍服务
Settings -> Accessibility -> TallBack
UiAutomator2.0-控件实现点击操作原理,最终的操作是由Uiautomation这个类实现的
编写服务类
onAccessibilityEvent(AccessibilityEvent event) 、onInterruput()
public class MyService extends AccessbilityService{
@Override
public void onAccessibilityEvent(AccessibilityEvent event){
int eventTypeId = event.getEventType();
switch(eventTypeId){
case AccessibilityEvent.TYPE_VIEW_CLICKED:
eventText = "TYPE_VIEW_CLICKED";
break;
.......
getSource() //获取事件源对应的结点信息
getText() //获取事件源的文本信息
并不是所有的事件都能通过getSource()方法获取到事件源,比如像通知消息类型的事件(TYPE_NOTIFICATION_STATE_CHANGED).
}
}
@Override
public void onInterrupt(){
}
@Override //系统成功绑定该服务时出发
public void onServiceConnected(){
//AccessibilityServiceInfo该类被用于配置AccessibilityService信息,该类中包含了大量用于配置的常量字段及用来xml 属性
AccessibilityServiceInfo xx=new AccessibilityServiceInfo();
xx.packageNames = ;
xx.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
xx.feedbackType=AccessibilityServiceInfo.FEEDBACK_SPOKEN;
}
@Override
public void getSystemService(String name){
//获取系统服务
}
}
然后在AndroidManifest.xml配置这个服务,打包apk
会在手机的无障碍服务中出现你安装的apk,但该服务处于关闭状态
获取窗口内容
一个服务可以配置为允许服务检索窗口内容,即获取窗口内容
整个窗口内容本质上是关于AccessibilityWindowInfo和AccessibilityNodeInfo的树结构,称之为内容树
不能只监控点击事件,要监控所有事件
canRetrieveWindowContent为Trye,便可以通过以下方法获取窗口内容
AccessibilityEvent.getSource(),findFocus(int),getWindow()或者getRootInActiveWindow()
服务的生命周期
- 该服务完全由系统管理,并遵循已有的服务周期
- 开启一个服务只能由用户在设置中打开,而关闭在设置中关闭或者服务本身调用disableSelf()关闭
- 系统绑定该服务之后,会调用onServiceConnected()方法,可以在该方法中做一些初始化的操作
检测服务是否开启
- 借助服务管理器AccessibilityManager来判断,但该方法不能检测app本身开启的服务
- AccessibilityManager是系统级别的服务,比如分发事件,查询系统中服务的状态等等
sendAccessibilityEvent(AccessibilityEvent event) 发送事件
getInstalledAccessibilityServiceList() 获取已安装到系统的服务列表
方法二
大部分系统属性都是在settings设置的,比如wifi,蓝牙状态,而这些信息存储在settings对应的数据库中
(system表和serure表),可以通过直接读取setting设置来判断相关服务是否开启
小知识
安装程序由PackageInstaller负责,其包名为com.android.packageinstaller。只需要监听该package下的安装信息节目和安装完成界面,并模拟点击安装完成操作,即可实现自动化安装