从事安卓开发也有两年多的时间了,从头开始整理下所学的东西,坚持!!!
一、Activity 活动
-
Activity 用于显示用户界面,用户通过 Activity 交互完成相关操作; 一个 App 允许有多个Activity
-
Activity使用流程
- Activiyt启动方式
显示启动:
①最常见的:
startActivity(new Intent(当前Act.this,要启动的Act.class));
②通过Intent的ComponentName:
ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全
限定类名") ;
Intent intent = new Intent() ;
intent.setComponent(cn) ;
startActivity(intent) ;
③初始化Intent时指定包名:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
startActivity(intent);
隐世启动:
通过Intent-filter的Action,Category或data来实现
- Activity的生命周期
- 组件间通信
Intent in = new Intent(A, B);
//1.传单个数据
in.putExtra("test","TTIT");
//2.传多个数据
Bundle b = new Bundle();
b.putInt("number", 100);
b.putString("test", "TTIT");
in.putExtras(b);
startActivity(in);
区别:Bundle的内部实际上是使用了HashMap<String, Object>类型的变量来存放putXxx()方法放入的值。简单地说,Bundle就是一个封装好的包,专门用于导入Intent传值的包
存:当我们用putExtras()方法时,所传入的Bundle会被转化为Intent的键值
取:直接使用this.getIntent()就可以得到传来的Intent,然后在这个Intent的基础上调用getExtras()就可以得到Bundle
- Activity四种启动模式以及任务栈
Activity 管理机制 :1. 我们的 APP 一般都是由多个 Activity 构成的,而在 Android 中给我们提供了一个 Task( 任务 ) 的概念, 就是将多个相关的 Activity 收集起来,然后进行 Activity 的跳转与返回 ;2. 当切换到新的 Activity ,那么该 Activity 会被压入栈中,成为栈顶! 而当用户点击 Back键,栈顶的 Activity 出栈,紧随其后的 Activity 来到栈顶!3.Task 是 Activity 的集合,是一个概念,实际使用的 Back Stack 来存储 Activity ,可以有多个 Task ,但是 同一时刻只有一个栈在最前面,其他的都在后台
1、standard:标准的启动模式
Activity默认的启动模式,依次入栈出栈,满足"先进后出"的原则。这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加
2、singleTop:栈顶复用模式
当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onNewIntent()方法会被调用,如果目标Activity不在栈顶,则跟standard一样创建新的实例
应用场景:消息通知,例如qq接收到消息后弹出activity,一次来10条消息,不可能启10个activity吧
3、singleTask:栈内复用模式
在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且该Activity上面的Activity会被清除,如果栈中没有,则创建新的实例。
注意: 如果启动模式为singleTask的activity已经在后台一个任务栈中,那么启动后,后台的任务栈将一起被切换到前台
应用场景:这个启动模式通常可以用来退出整个应用,将主activity设为singleTask,然后在要退出的activity中转到主activity,这样就把主activity之上的activity都清除掉,然后重写onNewIntent方法,在方法中加上一句finish(),将最后一个activity也干掉
4、singleInstance:单例模式
指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动
应用场景:浏览器
- 启动标志位
1.FLAG_ACTIVITY_NEW_TASK
默认启动标志,该标志控制创建一个新的Activity实例,首先会查找是否存在和被启动的
Activity具有相同的亲和性的任务栈 如果有,则直接把这个栈整体移动到前台,并保持栈中旧
activity的顺序不变,然后被启动的Activity会被压入栈,如果没有,则新建一个栈来存放被
启动的activity
Intent intent = new Intent(A.this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
2.FLAG_ACTIVITY_CLEAR_TOP
如果已经启动了四个Activity:A,B,C和D。在D Activity里,我们要跳到B
Activity,同时希望C finish掉,可以采用下面启动方式,这样启动B Activity,就会把D,
C都finished掉
Intent intent = new Intent(D.this, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
3.FLAG_ACTIVITY_SINGLE_TOP
从名字中不难看出该Flag相当于Activity加载模式中的singleTop模式,即原来Activity
栈中有A、B、C、D这4个Activity实例,当在Activity D中再次启动Activity D时,
Activity栈中依然还是A、B、C、D这4个Activity实例。
Intent intent = new Intent(D.this, D.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
二、Service 服务
程序:为了完成特定任务,用某种语言编写的一组指令集合 ( 一组 静态代码)进程: 运行中的程序 ,系统调度与资源分配的一个 独立单位,操作系统会 为每个进程分配一段内存空间!程序的依次动态执行,经历代码的加载,执行, 执行完毕的完整过程!线程:比进程更小的执行单元,每个进程可能有多条线程, 线程 需要放在一个 进程中才能执行,线程由程序 负责管理,而 进程则由系统进行调度!多线程的理解: 并行 执行多个条指令,将 CPU 时间片按照调度算法分配给各个 线程,实际上是分时 执行的,只是这个切换的时间很短,用户感觉到 " 同时 "而已!
-
Service 则是 Android 提供一个允许长时间留驻后台的一个组件,最常见的 用法就是做轮询操作!或者想在后台做一些事情,比如后台下载更新!
-
Service 的生命周期 :
- 生命周期函数解析:
1 ) onCreate () :当 Service 第一次被创建后立即回调该方法,该方法在整个生命周期 中只会调用一次!2 ) onDestory () :当 Service 被关闭时会回调该方法,该方法只会回调一次!3 ) onStartCommand ( intent , flag , startId ) :早期版本是 onStart ( intent , startId ), 当客户端调用 startService ( Intent ) 方法时会回调,可多次调用 StartService 方法, 但不会再创建新 的Service 对象,而是继续复用前面产生的 Service 对象,但会继续回调 onStartCommand( ) 方法!IBinder onOnbind(i ntent ) :该方法是 Service 都必须实现的方法,该方法会返回一个 IBinder 对象,app 通过该对象与 Service 组件进行通信!4 ) onUnbind ( intent ) :当该 Service 上绑定的所有客户端都断开时会回调该方法! - service启动方式: 下面分别对这三种绑定方式进行说明
1)StartService()启动Service
2)BindService()启动Service
PS:还有一种,就是启动Service后,绑定Service!
- StartService启动Service
① 首次启动会创建一个 Service 实例 , 依次调用 onCreate() 和 onStartCommand() 方法 , 此时Service 进入运行状态 , 如果再次调用 StartService 启动 Service, 将不会再创建新的 Service对象 , 系统会直接复用前面创建的 Service 对象 , 调用它的 onStartCommand() 方法!② 但这样的 Service 与它的调用者无必然的联系 , 就是说当调用者结束了自己的生命周期 , 但是只要 不调用stopService, 那么 Service 还是会继续运行的 !③ 无论启动了多少次 Service, 只需调用一次 StopService 即可停掉 Service
2.BindService启动Service
① 当首次使用 bindService 绑定一个 Service 时 , 系统会实例化一个 Service 实例 , 并调用其onCreate() 和 onBind() 方法 , 然后调用者就可以通过 IBinder 和 Service 进行交互了 , 此后如果再次使用 bindService 绑定 Service, 系统不会创建新的 Sevice 实例 , 也不会再调用 onBind() 方法 , 只会直接把 IBinder 对象传递给其他后来增加的客户端 !② 如果我们解除与服务的绑定 , 只需调用 unbindService(), 此时 onUnbind 和 onDestory 方法将会被调用 ! 这是一个客户端的情况 , 假如是多个客户端绑定同一个 Service 的话 , 情况如下 当一个客户完成和service 之间的互动后,它调用 unbindService() 方法来解除绑定。当所有的客户端 都和service 解除绑定后,系统会销毁 service 。(除非 service 也被 startService() 方法开启)③ 另外 , 和上面那张情况不同 ,bindService 模式下的 Service 是与调用者相互关联的 , 可以理解为" 一条绳子上的蚂蚱 ", 要死一起死 , 在 bindService 后 , 一旦调用者销毁 , 那么 Service 也立即终止 !通过 BindService 调用 Service 时调用的 Context 的 bindService 的解析bindService(Intent Service,ServiceConnection conn,int flags)service : 通过该 intent 指定要启动的 Serviceconn :ServiceConnection 对象 , 用户监听访问者与 Service 间的连接情况 , 连接成功回调该对象中的 onServiceConnected(ComponentName,IBinder) 方法 ; 如果 Service 所在的宿主由于异常终止或者其他原因终止 , 导致 Service 与访问者间断开 连接时调用onServiceDisconnected(CompanentName) 方法 , 主动通过 unBindService() 方法断开并不会调用上述方法 !flags: 指定绑定时是否自动创建 Service( 如果 Service 还未创建 ), 参数可以是 0( 不自动创建 ),BIND_AUTO_CREATE( 自动创建 )
3.StartService启动Service后bindService绑定
如果 Service 已经由某个客户端通过 StartService() 启动 , 接下来由其他客户端 再调用bindService( )绑定到该 Service 后调用 unbindService() 解除绑定最后在调用bindService() 绑定到 Service 的话 , 此时所触发的生命周期方法如下 :onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )PS: 前提是 :onUnbind() 方法返回 true!!! 说明: 调用了 unbindService后 Service 不是应该调用 onDistory() 方法么 ! 其实这是因为这个 Service 是由我们的StartService 来启动的 , 所以你调用 onUnbind() 方法取消绑定 ,Service 也是不会终止的 !得出的结论 : 假如我们使用 bindService 来绑定一个启动的 Service, 注意是已经启动的Service!!! 系统只是将 Service 的内部 IBinder 对象传递给 Activity, 并不会将 Service 的生命周期 与 Activity 绑定 , 因此调用 unBindService( ) 方法取消绑定时 ,Service 也不会被销毁!
三、BroadcastReceiver 广播接收器
-
为了方便 Android 系统各个应用程序及程序内部进行通信, Android 系统引入了一套广播机制。各 个应用程序可以对感兴趣的广播进行注册,当系统或者其他程序发出这条广播的时候,对发出的广 播进行注册的程序便能够收到这条广播。为此,Android 系统中有一套完整的 API ,允许程序只有的发送和接受广播。
-
两种基本的广播类型: 标准广播、有序广播
标准广播:
是一种同步执行的广播,在广播发出之后,优先级高的广播接收器可以优先接收到这条广播,
并可以在优先级较低的广播接收器之前截断停止发送这条广播。
发送方式:
Intent intent=new Intent("com.example.dimple.BROADCAST_TEST");
sendOrderBroadcast(intent,null);//第二个参数是与权限相关的字符串。
有序广播:
是一种同步执行的广播,在广播发出之后,优先级高的广播接收器可以优先接收到这条广播,
并可以在优先级较低的广播接收器之前截断停止发送这条广播。
发送方式:
Intent intent=new Intent("com.example.dimple.BROADCAST_TEST");
sendOrderBroadcast(intent,null);//第二个参数是与权限相关的字符串。
-
注册广播 :
在Android的广播接收机制中,如果需要接收广播,就需要创建广播接收器。而创建广播接收器的
方法就是新建一个类(可以是单独新建类,也可以是内部类(public)) 继承自
BroadcastReceiver
class myBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//不要在广播里添加过多逻辑或者进行任何耗时操作,因为在广播中是不允许开辟
线程的, 当onReceiver( )方法运行较长时间(超过10秒)还没有结束的话,那么程序会报错
(ANR), 广播更多的时候扮演的是一个打开其他组件的角色,比如启动Service,Notification
提示, Activity等!
}
}
-
两种方式注册广播:
1、动态注册的广播接收器可以自由的控制注册和取消,有很大的灵活性。但是只能在程序启动之后才 能收到广播,此外,不知道你注意到了没,广播接收器的注销是在onDestroy() 方法中的。所以广播接收器的生命周期是和当前活动的生命周期一样。2、静态注册的广播不受程序是否启动的约束,当应用程序关闭之后,还是可以接收到广播。
所谓动态注册是指在代码中注册。步骤如下 :
- 实例化自定义的广播接收器。
- 创建IntentFilter实例。
- 调用IntentFilter实例的addAction()方法添加监听的广播类型。
- 最后调用Context的registerReceiver(BroadcastReceiver,IntentFilter)动
态的注册广播。
PS:这里提醒一点,如果需要接收系统的广播(比如电量变化,网络变化等等),别忘记在
AndroidManifest配置文件中加上权限。
另外,动态注册的广播在活动结束的时候需要取消注册:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
}
静态注册
<receiver
android:name="com.ttit.core.broadcastreceiver.MyBRReceiver2">
<intent-filter>
<action
android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
四、ContentProvider 内容提供者
ContentProvider应用场景: 我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如 手机联系人,短信等!我们想对这些数据进行读取或者修改,这就需要用ContentProvider了!
我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!
- 自定义ContentProvider
我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用 到 ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!
- ContentObserver:内容观察者,目的是观察特定Uri引起的数据库的变化,方便监听插入数据库中数据的变化
创建内容观察者 ContentObserver
2、注册监听 registerContentObserver
3、刷新数据库改变 onChange (内容观察者即可收到消息)
4、注销监听 unregisterContentObserver (页面销毁或程序关闭的时候)
1、ContentProvider——内容提供者
对外提供数据,通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
2、ContentResolver——内容解析者
按照一定规则访问内容提供者的数据(其实就是调用内容提供者自定义的接口来操作它的数据)。
3、ContentObserver——内容监听器
监听(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。
ContentResolver.notifyChange(uri) 发出消息。
ContentResolver.registerContentObserver() 监听消息。