Activity: Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑;
Service:后台服务于Activity,没有界面,常用来执行耗时的操作;封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事务,定义好需要接受的Intent提供同步和异步的接口
BroadcastReceiver:接受一种或者多种Intent作触发事件,接受相关消息,做一些简单处理,转换成一条Notification,统一了Android的事件广播模型。1.广播接受者,用来接收广播;2.接收到广播后可以执行某些操作,是一种进程间的通信方式;。
ContentProvider:是Android提供的第三方应用数据的访问方案,可以派生Content Provider类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的接口模型,大大简化上层应用,对数据的整合提供了更方便的途径。
Activity主要生命周期的方法说明:
onCreate(Bundle savedInstanceState):创建Activity时调用(第一次);操作:设置布局文件、初始化视图、绑定数 据文件等;设置在该方法中,还以Bundle的形式提供对以前储存的任何状态的访问;
onStart():Activity变为在屏幕上对用户可见时调用;
onResume():Activity开始与用户交互时调用(无论是启动还是重新启动一个活动,该方法总是被调用的);
onPause():Activity被暂停或收回cpu和其他资源时调用,该方法用于保存活动状态的,也是保护现场;
onStop():Activity被停止并转为不可见阶段及后续的生命周期事件时调用;
onRestart():重新启动Activity时调用。该活动仍在栈中,而不是启动新的活动;
onDestroy():销毁Actvity;1)调用了finish()方法,2)系统资源不够用了
必调用的三个方法:onCreate()创建 --> onStart()可见 --> onResume()可操作,用AAA表示
(1)父Activity启动子Activity,子Actvity退出,父Activity调用顺序如下
AAA --> onPause()暂停 --> onStop()被完全遮盖 --> onRestart()重启动--> onStart()可见-->onResume()可操作
(2)用户点击Home,Actvity调用顺序如下
AAA --> onPause() --> onStop()-->onDestroy()
(3)调用finish(), Activity调用顺序如下
AAA --> onPause() --> onStop() --> onDestroy()
(4)在Activity上显示dialog,Activity调用顺序如下
AAA
(5)在父Activity上显示透明的或非全屏的activity,Activity调用顺序如下
AAA --> onPause()
(6)设备进入睡眠状态,Activity调用顺序如下
AAA --> onPause()
两种,一种是tweened animation(补间动画)、还有一种是frame by frame animation(帧动画)。
一般用第一种Tween动画,这种实现方式可以使视图组件移动(translate)、缩放(scale)、旋转(rotate)以及产生透明度的变化(alpha);
另一种Frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。
首先写一个类继承BroadcastReceiver;
一种是代码动态注册:
//生成广播处理
smsBroadCastReceiver = newSmsBroadCastReceiver();
//实例化过滤器并设置要过滤的广播
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注册广播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,intentFilter);
另一种是在AndroidManifest.xml中配置广播:
两种注册类型的区别是:
1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
ANR:在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR 给用户。
不同的组件发生 ANR 的时间不一样,主线程(Activity、Service)是 5 秒,BroadCastReceiver 是 10 秒。
解决方案:Activity应该在它的关键生命周期方法(如onCreate()和 onResume())尽可能少的去做创建操作。将所有耗时操作,比如访问网络,Socket 通信,查询大量 SQL 语句,复杂逻辑计算等都放在子线程中去完成(或者是使用异步请求,如数据库操作),主线程为子线程提供一个Handler,以便完成时能够提交给主线程。
抛出运行时异常时就会导致Force Close,比如空指针、数组越界、类型转换异常等等。
捕获:可以通过logcat查看抛出异常的代码出现的位置,然后到程序对应代码中进行修改。
避免:编写程序时,要思维缜密,在可能出现异常的地方都作相应的处理,增强程序的健壮性。
Android中的service类似于windows中的service,service一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
启用:
第一步:继承Service类
第二步:在AndroidManifest.xml文件中的
1)使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。
2)使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。
停用:
采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,
接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并
不会导致多次创建服务,但会导致多次调用onStart()方法。
采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用
onDestroy()方法。
采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,
接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会
导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务
解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
简单的说,Handler获取当前线程中的looper对象,looper用来存放从MessageQueue中取出的Message,再由Handler进行Message分发和处理,按照先进先出执行。
MessageQueue(消息队列):用来存放通过Handler发送的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列。
Handler:是Message的主要处理者,负责Message的发送,Message内容的执行处理。例如将消息发送到消息队列(sendMessage),更新UI组件(实现该类的handleMessage方法)
Looper:是Handler和消息队列之间的通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放到队列。Looper也把消息队列里的消息广播给所有的Handler,Handler收到消息后再调用handleMessage进行处理。
Message:消息的类型,理解为线程间交流的信息,处理数据后台线程需要更新UI,在Handler类中的handleMessage方法中得到单个的消息进行处理。
Handler机制的大致流程:
1.在Looper.loop()方法运行开始后,循环的按照接收顺序取出MessageQueue里面的非NULL的Message。
2.一开始MessageQueue里面的Message都是NULL的,当Handler.sendMessage(Message)到MessageQueue,该函数里面设置了那个Message对象的target属性是当前Handler对象。随后Looper取出了那个Message,则调用该Message的target指向的Handler的dispatchMessage函数对Message进行处理。在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:
1)Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作
2)Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理。
3)处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
由此可见,实现的handleMessage方法时优先级最低的。
3.Handler处理完该Message后,Looper则设置该Message为NULL,以便回收。
主线程和其他子线程如何交互,传送信息,最终执行处理信息:
判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行。
1)当Handler对象的构造函数为空时,则为当前所在线程的Looper;
2)Looper.getMainLooper()得到的是主线程的Looper对象,Looper.myLooper()得到的是当前线程的Looper对象
1)一个activity呈现了一个用户可以操作的可视化用户界面;
2)一个service不包含可见的用户界面,而是在后台无限地运行,可以与一个activity绑定,通过绑定暴露出来接口并与其进行通信;
3)一个broadcast receiver是一个接收广播消息并作出回应的component,broadcast receiver没有界面;
4)一个intent是一个Intent对象,它保存了消息的内容。对于activity和service来说,它指定了请求的操作名称和待操作数据的URI,Intent对象可以显式的指定一个目标component。如果这样的话,android会找到这个component(基于manifest文件中的声明)并激活它。但如果一个目标不是显式指定的,android必须找到响应intent的最佳component。
它是通过将Intent对象和目标的intent filter相比较来完成这一工作的;
5)一个component的intent filter告诉android该component能处理的intent。intent filter也是在manifest文件中声明的。
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged()方法
XML解析主要有三种方式,SAX、DOM、以及Android推荐的PULL。
1.SAX解析:
2.DOM解析:
3.PULL解析:
Android系统采用了分层架构,从上到下层分别是应用程序层、应用程序框架层、系统运行库层、Linux核心层