架构:
应用框架层(Java API Framework)所提供的主要组件:
名称 | 功能描述 |
---|---|
Activity Manager(活动管理器) | 管理各个应用程序生命周期,以及常用的导航回退功能 |
Location Manager(位置管理器) | 提供地理位置及定位功能服务 |
Package Manager(包管理器) | 管理所有安装在Android系统中的应用程序 |
Notification Manager(通知管理器) | 使得应用程序可以在状态栏中显示自定义的提示信息 |
Resource Manager(资源管理器) | 提供应用程序使用的各种非代码资源,如本地化字符串、图片、布局文件、颜色文件等 |
Telephony Manager(电话管理器) | 管理所有的移动设备功能 |
Window Manager(窗口管理器) | 管理所有开启的窗口程序 |
Content Provider(内容提供者) | 使得不同应用程序之间可以共享数据 |
View System(视图系统) | 构建应用程序的基本组件 |
四大组件:
1、Activity组件,它一个单独的窗口,程序流程都必须在[Activity]中运行,所有它是最基本的模块。
2、service组件,用于在后台完成用户指定的操作。
3、content provider组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
4、broadcast receiver组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。
四大组件可以通过 Intent 进行互相通信
Intent
Intent是一种运行时绑定(run-time binding)机制,它是一种基于某种想要被表露的意图的被动式数据结构,它能在程序运行过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来完成请求。
Intent 结构
action – 想要实施的动作,例: ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.
data – 具体的数据,一般由以Uri表示,例:通讯录中的某条记录,会以Uri来表示
category – 为实施的动作添加的额外信息,即Intent组件的种类信息,一个Intent对象可以有任意个category,例:CATEGORY_LAUNCHER 意味着,它应该在启动器中作为顶级应用而存在
type – 显示指定Intent的数据类型(MIME类型 - 多用途互联网邮件扩展,Multipurpose Internet Mail Extensions),例:一个组件是可以显示图片数据的而不能播放声音文件。很多情况下,data类型可在URI中找到,比如content:开头的URI,表明数据由设备上的content provider提供。但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导
MIME类型有两种:单个记录格式、多个记录格式
component – 指定Intent的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的,例如:Intent it = new Intent(Activity.Main.this, Activity2.class); startActivity(it);
extras – 附加信息,例如:it.putExtras(bundle) - 使用Bundle来传递数据;
Activity组件:
Activity可以看成是安卓系统的根本,在这个根本上才可以进行其他的工作,因为在安卓系统里运行的所有的程序,它的流程都必须在【Activity】中运行,所有他是最基本的模块。它的作用是一个框架或页面,每个程序会有多个【Activity】组成。
(1)一个Activity通常就是一个单独的屏幕(窗口)。
(2)Activity之间通过Intent进行通信。
(3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。
Activity生命周期:
onCreate:表示Activity正在被创建,这是生命周期的第一个方法。 在这个方法中做初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity所需数据等,子类在重写onCreate()方法的时候必须调用父类的onCreate()方法,即super.onCreate(),否则会抛出异常。此方法的传参Bundle为该Activity上次被异常情况销毁时保存的状态信
onRestart: 表示Activity 正在重新启动。一般情况下,当前Activity从不可见重新变为可见状态时,onRestart 就会被调用。这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停,即onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况
onStart: 表示Activity正在被启动,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互。可以理解为Activity已经显示出来了,但是我们还看不到。
onResume:表示Activity已经可见,并且出现在前台并开始活动。onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume 的时候Activity才显示到前台。
onPause:表示Activity 正在停止,正常情况下紧接着onStop就会被调用。此时可以做存储数据、停止动画等工作,但是不能太耗时,因为这会影响到新Activity的显示,旧的onPause 必须先执行完,新Activity的onResume才会执行。
onStop: 表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时,如取消网络连接、注销广播接收器等。
onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,可以做回收工作和最终的资源释放。
Activity活动状态:
运行状态,当一个活动位于返回栈的栈顶时,活动处于运行状态
暂停状态,当一个活动不再处于栈顶状态,但仍可见,活动进入暂停状态
停止状态,当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入停止状态。系统仍然可能会为这种活动保存相应的状态和位置,但如果出现内存缺少,处于停止状态的活动可能会被回收。
销毁状态,当一个活动从返回栈移除之后成为销毁状态,系统倾向于回收该类活动。
Android是使用返回栈来管理活动的。启动模式一共有4种,分别是standard、 singleTop、 singleTask和singleInstance,可以在AndroidManifest.xml中通过给 标签指定android:launchMode 属性来选择启动模式。
standard模式,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在, 每次启动都会创建该活动的一个新的实例。
singleTop模式,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
singleTask模式,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例, 如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
singleInstance模式下会有一个单独的返回栈来管理这个共享的活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题
service组件:
service分为StartedService和BoundService。
1.StartedService和启动他的Activity不同生共死,BoundService和启动给他的Activity同生共死。
2.无论是StartedService或者是BoundService,只要service没有被实例化,就都会被Creat。
3.StartedService和BoundService只要已实例化,就都不会再调用onCreate,但StartedService每次都会再调用onStartCommand,而BoundService若已绑定,则不会再调用onBind
started service(启动服务)是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
ContentProvider:
ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
当应用需要通过ContentProvider对外共享数据时,需要继承ContentProvider并重写下面方法:
public class PersonContentProvider extends ContentProvider{
public boolean onCreate()
public Uri insert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)}
Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由三部分组成:协议、authority和path:
ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
1.1 要操作person表中id为10的记录,可以构建这样的路径:/person/10
1.2 要操作person表中id为10的记录的name字段, person/10/name
1.3 要操作person表中的所有记录,可以构建这样的路径:/person
1.4 要操作xxx表中的记录,可以构建这样的路径:/xxx
1.5要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
1.6如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
broadcast receiver:
广播分为两种类型: 标准广播和有序广播
标准广播 (Normal broadcasts) 是一种完全异步执行的广播, 在广播发出之后, 所有的广播接收器几乎都会在同一时刻接收到这条广播消息,无序。广播效率高,无法被截断的。
有序广播 (Ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。有先后顺序,优先级高的广播接收器就可以先收到广播消息,并且可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。
注册方式:动态注册(通过java代码进行注册)、静态注册(在AndroidManifest.xml中注册,开机就启动)。动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。
本地广播:该机制下广播只能在应用程序内部传递,接收器也只能接受本应用程序发出的广播,只能用java代码动态实现。
粘性广播:这种广播会一直保留最后一条广播,即使已经有广播接收器处理了该广播,一旦又有匹配的官博接收器被注册,该粘性广播仍会被接收。
android中的任务(activity栈)
a)任务其实就是activity的栈,它由一个或多个Activity组成,共同完成一个完整的用户体验。栈底的是启动整个任务的Activity,栈顶的是当前运行的用户可以交互的Activity,当一个activity启动另外一个的时候,新的activity就被压入栈,并成为当前运行的activity。而前一个activity仍保持在栈之中。当用户按下BACK键的时候,当前activity出栈,而前一个恢复为当前运行的activity。栈中保存的其实是对象,栈中的Activity永远不会重排,只会压入或弹出。
b)任务中的所有activity是作为一个整体进行移动的。整个的任务(即activity栈)可以移到前台,或退至后台。
c)Android系统是一个多任务(Multi-Task)的操作系统,可以在用手机听音乐的同时,也执行其他多个程序。每多执行一个应用程序,就会多耗费一些系统内存,当同时执行的程序过多,或是关闭的程序没有正确释放掉内存,系统就会觉得越来越慢,甚至不稳定。为了解决这个问题,Android引入了一个新的机制,即生命周期(Life Cycle)。
很多耗时程序用多线程处理,但子线程不能修改主线程生成的UI,解决方法有两种:1、使用Handler,子线程发送消息到主线程,主线程来修改UI。2、
数据存储
4种方式用于简单地实现数据持久化功能,即文件存储、SharedPreferences存储、contentprovider存储以及数据库存储,真机测试是没有办法通过File Provider查看保存的数据的。
数据存储方式 | 文件保存目录 |
---|---|
File | /data/data/< 包名>/files/< 文件名> |
sharedPreferences | /data/data/< 包名>/shared_prefs/< 文件名> |
SQLite | /data/data/< 包名>/databases/< 数据库名> |
外部存储SDcard | /storage/emulated/0/< 文件名>: |
File文件存储:写入和读取文件的方法和Java中实现l/O的程序一样,程序外本地数据存储,非结构化数据–文件存储
SharedPreferences存储:一种轻型的数据存储方式,常用来存储一些简单的配置信息,本质是基于XML文件存储key-value键值对数据。应用内数据存储方式,程序外不可访问
SQLlite数据库存储:一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,在存储大量复杂的关系型数据的时可以使用。结构化数据—SQLite数据库存储
ContentProvider:四大组件之一,用于数据的存储和共享,不仅可以让不同应用程序之间进行数据共享,还可以选择只对哪一部分数据进行共享,可保证程序中的隐私数据不会有泄漏风险。