Android四大组件详解

    
     博主接触Android开发将近一年,从最初的JavaSE开始,到Android基础,一直学的糊糊涂涂,最近想整理一番
   android基础, 顺便把自己的学习开发经验分享给大家(小白一个),大家觉得有什么建议可以评论。
    四大组件 Activity,Service,BroadCastReceiver,ContentProvider,是android中基础的基础,
    所有android开发都离不开这四大基础组件。
 1.Activity    
     从Activity说起,activity从字面上的意思理解是活动行动的意思, 在Android中,
   activity指与用户交互的界面,从你打开一个android应用所见到的第一个页面,就是一个Activity
   Activity作为一个可见的界面,给用户以良好的体验很重要,所以布局的漂亮与否决定一个应用用户体验
   及开发人员 的技术水平,布局肯定是要掌握的咯(今天不讲布局).我们开发常见的有
   FragmentActivitiyListActivity ,PreferenceActivity ,TabAcitivty等… 
        先从Activity的生命周期讲起,一个activity的生命周期就像我们一样,从出生到童年,青年,中年,老年
    最后入土.Activity从创建到销毁有多种状态,从一种状态到另一种状态时会激发相应的回调方法,从onCreate(),
    onStart(),onPause(),onResume(),onstop(),onDestroy(),到onRestart()等方法.(最常使用)。
    
      首先我们来说说onCreat()方法,谷歌官方的解释是:当这个界面第一次创建的时候执行这个方法,当然
   一般情况下,在一个应用中这个方法只会执行一次,(横竖屏切换),既然这个方法最先执行,那我们就可以在
   这个方法体里面做一些初始化的操作,如 初始化view(setCountentView(view)),寻找控件 findViewById(id),
   初始化一些数据等等。
        执行完oncreate方法界面展示后,即当Activity变成可见的时候,开始执行onStart()方法 ,这个方法和
  onStop()方法对应。这个方法的用处不怎么大。
        onResume()方法,当一个界面可以和用户交互,获取到焦点的的时候,执行这个方法,什么是和用户交互? 
  比如说,你点击屏幕上的按钮,图片等等,activity会给出不同的反应。
        onPause()方法和onResume()方法对应,即activity不能和用户交互的,activity失去焦点,界面上的view
  不能被点击的时候执行。
       onStop()方法,当activity不可见的时候,执行这个方法,如从一个activity跳转到另一个activity时,跳转
  前的activity被跳转后的activity遮挡,就会执行onStop()这个方法
       onRestart()方法,从第一个activity跳转到第二个activity,再返回第一个 activity时,就会执行这个方法
  界面重新变得可见就会执行这个方法。
       onDestroy()方法,当一个activity销毁的时候调用这个方法,与onCreate()对应。
 
     简单来说,这些方法都是两两对应的,onCreate创建与onDestroy销毁;onStart可见与onStop不可见;
     onResume可编辑(即获得焦点)与onPause(失去焦点)。
   
       
横竖屏切换生命周期比较特殊,不同activity跳转,而是销毁当前activity并重新创建
在Androidmainfest清单文件中声明android:screenOrientation="portrait"属性可以限制不可横竖屏切换。
      
   下面是一个Demo,
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);System.out.println("onCreate--------------------");}//点击按钮实现页面跳转  TestActivitypublic void click(View v) {Intent intent = new Intent(this,TestActivity.class);startActivity(intent);}//当Activity销毁的时候执行@Overrideprotected void onDestroy() {System.out.println("onDestroy--------------------");super.onDestroy();}//当页面可见的时候调用@Overrideprotected void onStart() {System.out.println("onStart--------------------");super.onStart();}//当Activity 不可见执行@Overrideprotected void onStop() {System.out.println("onStop--------------------");super.onStop();}//当Activity正在进行交互  按钮可以被点击了@Overrideprotected void onResume() {System.out.println("onResume--------------------");super.onResume();}//当acctivity不再进行交互 按钮不可以被点击@Overrideprotected void onPause() {System.out.println("onPause--------------------");super.onPause();}//当界面重新加载@Overrideprotected void onRestart() {System.out.println("onRestart--------------------");super.onRestart();}}
 
   上面是很简单的内容,接下来我们来扯一扯Activity的四种启动模式
[1]标准 standard,大部分应用都是这个标准启动模式。 
  
[2]singleTop 单一顶部模式   当我们把Activity配置成 singleTop启动模式的时候 ,当我们在开启这个Activity的时候 就会检查当前任务栈的栈顶是否有这个实例存在,
如果存在就不会创建新的实例,而是直接复用这个实例 ,应用场景:singleTop :浏览器书签页面  
 
  [3]singleTask 当我们 把Activity设置成singleTask启动模式 会检查当前任务栈 是否有实例开启 ,如果有实例开启,就会直接复用这个实例 ,
并且会把这个实例上面其他的Activity 也清空,当前任务栈只有一个实例存在  
应用场景:singeTask : 浏览器浏览的页面  节约内存 
  [4]singleinstance :如果把一个Activity配置这种启动模式,系统会为这个Activity单独创建一个任务栈,这个Activity在自己的任务栈里面存在
应用场景 singleInstance :来电页面  做销售   

  四种启动模式都需要在清单文件下的Activity节点下配置,如果不配置,则默认标准standard开启activity
        <activityandroid:name=".SecondActivity" android:launchMode="singleInstance"></activity>
        Activity暂且告一段落.
       2.Service
        Android下的服务是在后台运行 也是没有界面 可以理解成是没有界面的Activity,Android系统会为每个
    应用程序创建一个进程和线程(主线程),而开启一个服务就会创建一个进程,可以在后台看到。
    我们来分析一下进程:
    进程按优先级分5中:
           1.Foreground process 前台进程,正在和用户交互 相当于Activity执行了onResume方法这个进程最不容易被系统杀死。         
          
           2.Visible Process  可视化进程,用户可以看得见,但用户不能进行交互,相当于Activity执行了onPause()方法。
          
           3.Service Process   服务进程 , 当进程里面通过startService开启一个服务,这时候就属于服务进程。
          
           4. Background Process   后台进程, 相当于Activity执行了onStop()方法。
          
           5. Empty  Process   空进程    空进程不会维持任何运行的组件,空进程最容易被杀死,有时候它没有被立刻杀死的目的是为下一次打开应用程序时提供打开的速度。
        
          在系统运行内存不足的情况下,会检查正在正在运行的进程,杀死优先级低的进程来腾出内存。

       我们开启服务有两种方式: StartService() 和 BindService().
         starService 开启一个服务,会执行onCreate()方法,和onStart()方法,如果服务已经开启,只会执行onStart()方法。
     服务开启后,就会在后台长期运行,可以在设置界面找到,我们可以在设置界面手动关闭它,服务就会停止运行。
         startService开启服务也叫做非绑定模式开启服务 ,生命周期  第一次执行的方法有 onCreate().onstartCommand(),到service关闭的时候执行onDestroy()方法。

        bindService开启服务也叫做绑定模式开启服务,生命周期 第一次执行的方法有 onCreate(), onBind()方法,    销毁的时候执行onUnBind(),onDestroy()方法, bindService开启服务有个特点,它在设置界面时找不到的,所以我们无法手动在设置界面销毁它,       不过它的生命周期依附于Activity,当Activity销毁的时候,这个服务也就跟着销毁。

    上面两种生命周期实在相对单纯的模式下的情形,我们在开发的过程中还必须注意Service实例只会有一个,也就是说如果当前要启动的Service已经存在了那么就不会再次创建该Service当然也不会调用onCreate()方法;   一个Service可以被多个客户进行绑定,只有所有绑定对象都执行了onBind()方法后该Service才会销毁,不过如果有一个用户执行了onStart()方法,那么这个时候如果其他所有的bind客户都执行了unBind()。     该Service也不会销毁,很多应用都是用startService和bindService混合开启服务,比如音乐播放器,第三方支付等

      这时我们可能会有一个疑问:既然有StartService开启服务,为什么还要用bindService开启服务?          目的就是为了使用bindserivce调用服务里面的方法          这时就出现了解决进程间的通信问题:IPC,          而使用IPC就需要使用   aidl.          aidl :Android inteface defation language Android接口定义语言      
使用aidl语言的步骤 
   [1] 有一个服务 服务里面有一个方法  这个方法在另外一个应用里面调用  
[2]在服务的内部定义一个中间人对象(IBinder的实例)
[3]在onbind方法里面把我们定义的中间人对象返回
[4]把你想暴露的方法都定义在接口里
   [5]把定义的接口Iservice.java 文件变成aidl文件   注意aidl语言不认识public
   [6]系统会自动生产一个Iservice.java文件  生产一个类 stub 系统会报错. 把我们定义的中间人对象直接继承Stub
   [7]想保证2个应用程序使用的是同一个aidl文件 谷歌要求aidl文件所生成的包名要相同 
   [8]获取中间人对象方式不一样  是通过stub类中的一个静态方法获取我们定义中间人对象
[9]通过获取到的中间人对象,调用服务里面的方法,实现IPC通信。

  两种开启服务的小Demo:       
 public class MainActivity extends Activity {private MyConn conn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}// 点击按钮开启服务public void click1(View v) {Intent intent = new Intent(this, FirstService.class);startService(intent);}// 点击按钮关闭服务public void click2(View v) {Intent intent = new Intent(this, FirstService.class);stopService(intent);}//点击按钮 通过bindservice 去连接服务public void click3(View v) {Intent intent = new Intent(this, FirstService.class);conn = new MyConn();bindService(intent, conn, BIND_AUTO_CREATE);}//点击按钮 停在服务 public void click4(View v) {Intent intent = new Intent(this, FirstService.class);stopService(intent);}//当Activity销毁的时候 @Overrideprotected void onDestroy() {//取消绑定服务 unbindService(conn);super.onDestroy();}//监听服务的状态 private class MyConn implements ServiceConnection{//当服务连接成功的时候调用@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {}//失去连接的时候调用@Overridepublic void onServiceDisconnected(ComponentName name) {}}
}
</pre><pre name="code" class="java">
public class FirstService extends Service {
  //当通过bindservice 连接成功的时候执行@Overridepublic IBinder onBind(Intent intent) {System.out.println("onBind");return null;}//当service第一次创建的时候调用@Overridepublic void onCreate() {System.out.println("onCreate");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("onStartCommand");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {System.out.println("onDestroy");super.onDestroy();}
}
 3.BroadCastReceiver  

      BroadCastReceiver是Android四大组件之一,主要用于接收系统或者app发送的广播事件      广播分两种: 有序广播和无序广播      内部通信实现机制:通过Android系统的Binder机制实现通信的     无序广播:sendBroadcast()方法发送的广播为无序广播,无序广播逻辑上可以被任何广播接受者接收到,优点是效率高。缺点是一个接收者不能将处理结果传递给下一个接收者,传递的数据在传输过程中不能被修改,并无法终止广播的传播。
      有序广播:sendOrderedBroadcast()方法发送的广播为有序广播,有序广播依次传播,列如有三个广播接收者A,B,C, 优先级是A>B>C,
       此时发送一条广播,那这个消息先传给A,再传给B, 最后传给C,每个接收者都有权终止广播,比如B终止广播,C就无法接受到,
       此外A接收到广播后可以对结果对象进行操作,当广播传给B时,B可以从结果对象中获取A存入的数据。

  在通过context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,initialCode, initialData, initialExtras);时我们可以指定resultReceiver广播接收者,     这个接收者我们可以认为是最终接收者,通常情况下如果比他优先级更高的接收者如果没有终止广播,那么他的onReceive方法会被执行两次,     第一次是正常的按照优先级顺序执行,第二次是作为最终接收者接收,如果比他优先级高的接收者终止了广播,那么他依然能接收到广播。     在我们的项目中经常使用广播接收者接收系统通知,比如开机启动,sd卡挂载,低电量,外拨电话,锁屏等等,     如果我们做的是播放器,那么监听到用户锁屏后我们应该将我们的播放器暂停等。

       BroadcastReceiver有两种注册方法,在Androidmainfest中注册广播接收者称为静态注册,在代码中注册称为动态注册。    静态注册的广播接收者只要app在系统中注册则可以一直接收到广播消息,动态注册的广播接收者当注册的activity或Service销毁了那么久接收不到广播了,     所以一般应用都是静态注册的,有一些操作特别频繁的广播事件在Androidmainfest中注册无效的,      如手机锁屏广播,在代码中我们可以用registerReceiver()方法去注册广播。

  需要注意的地方:    1.BroadcastReceiver的生命周期是非常短暂的,在接收广播的时候创建,onReceiver()方法结束之后销毁

       2.  广播接收者中不要做一些耗时的工作,否则会弹出Application No Response(应用无响应anr)错误对话框,,一般耗时的较长的操作最好放在服务中完成。

        3.最好也不要在广播接收者中创建子线程做耗时操作,因为广播接收者被销毁后进程就成为空进程,而空进程很容易被系统杀掉。     

       Android中引入广播机制的用意 :

        1.程序间互通消息(例如在自己的应用程序内监听系统的来电)

        2.效率上(参考UDP的广播协议在局域网的方便性)

        3.设计模式上(反转控制的一种应用,类似监听者模式)
发送和接收广播的小Demo;
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//点击按钮发送一条无序 广播 public void click(View v) {Intent intent = new Intent();//设置发送广播的事件intent.setAction("com.itcast.customreceiver");intent.putExtra("name", "每天晚上7点准时开整~~");//发送广播sendBroadcast(intent);}}
</pre></div><div><pre name="code" class="java"><pre name="code" class="java">public class ReceiveCusomReceiver extends BroadcastReceiver {//这个方法接收我们自定义发送的广播 @Overridepublic void onReceive(Context context, Intent intent) {//终止广播abortBroadcast();String name = intent.getStringExtra("name");Toast.makeText(context, name, 0).show();}}

4.ContentProvider

最后我们来介绍一下内容提供者ContentProvider

在Android中如果想将自己应用的数据(多为数据库中的数据)提供给第三方应用,那么我们只能通过ContentProvider来实现了。

ContentProvider是应用程序之间共享数据的接口,使用的时候首先自定义一个类继承ContentProvider,然后重写query,insert,updata,delete等方法。

因为内容提供者是四大组件之一,因此必须在AndroidMainfest文件中进行注册。

代码如下:

public class OtherActivity extends ContentProvider {@Overridepublic boolean onCreate() {return false;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {return null;}@Overridepublic String getType(Uri uri) {return null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {return 0;}
}

AndroidMainfest中注册:

  <provider android:name="com.example.mangjiang.otherprovider"android:exported="true"></provider>

第三方可以通过内容解析者ContentResolver来访问该Provider,另外还有内容观察者ContentObserver,

这里不一一赘述。

 
          Android为什么要有Activity,Service,BroadCastReceiver,ContentProvider?
        因为现在的移动开发模式基本上也是照搬web那一套MVC框架,只不过改了点嫁妆而已,四大组件本质上就是为了实现移动或者说是嵌入式设备上的MVC架构,
        它们之间有时候是一种相互依存的关系,有时候又是一种补充关系。
      
     
       这篇博客很多地方是理论知识,或许会觉得很枯燥,耐心阅读,掌握这些基础知识,对以后的android开发会有很大的帮助!
         
        有什么不足的地方请各位大牛指点!

Android基础四大组件详解相关推荐

  1. Android笔记——四大组件详解与总结

    android四大组件分别为activity.service.content provider.broadcast receiver. -------------------------------- ...

  2. Android中的四大组件详解

    Android中的四大组件详解 我们都知道Android系统应用层框架中,为开发者提供了四大组件来便于应用的开发,它们是Activity.Service.BroadcastReceiver.Conte ...

  3. android 广播的权限,Android四大组件详解之BroadcastReceiver广播接收者

    Android四大组件详解---BroadcastReceicer广播接收者 广播有两个角色,一个是广播发送者,另一个是广播接收者. 广播按照类型分为两种,一种是全局广播,另一种是本地广播 全局广播: ...

  4. Android基础——四大组件之Activity

    这几天继续回顾了一些Android基础方面的知识,今天跟大家一起回顾下Android四大组件中的Activity.虽然很基础,但工欲善其事,必先利其器.我们只有打好夯实的基础,才能在技术开发这条道路上 ...

  5. Android 基础四五六之:四大组件详解

    Android 四大组件 android四大组件分别是:Activity, service,content provider,broadcast receiver 今天就带大家详细的学一波基本功,需要 ...

  6. 【Android】Android中ContentProvider组件详解

    原文来自:http://blog.csdn.net/zuolongsnail/article/details/6566317 ContentProvider(内容提供者)是Android中的四大组件之 ...

  7. Android中ContentProvider组件详解

    一.Android四大组件 Android四大组件是Activity, Service, Content Provider,Broadcast Receiver. Activity作为程序界面,直接与 ...

  8. Android基础四大组件之Activity的启动过程源码解析

    前言 Activity是Android中一个很重要的概念,堪称四大组件之首,关于Activity有很多内容,比如生命周期和启动Flags,这二者想要说清楚,恐怕又要写两篇长文,更何况分析它们的源码呢. ...

  9. Android中BroadcastReceiver组件详解

    Android系统的4个组件终于还剩一种组件了BroadcastReceiver,这个组件是全局监听器,可以监听系统全局的广播消息,可以方便的实现系统中不同组件之间的通信 BroadcastRecei ...

最新文章

  1. php 控制器自动,ThinkPHP 新建控制器
  2. 1001. A+B Format (20)---------------PAT开始
  3. 用U盘或移动硬盘安装Windows7 (超简单制作Win7安装U盘方法)
  4. 数据结构视频教程 严蔚敏
  5. C++程序设计:字符图形输出(数字三角形)
  6. oceanbase安装
  7. 手机端 19FPS 的实时目标检测算法:YOLObile
  8. 5. 等可能概型(古典概型)
  9. interrupt、interrupted 、isInterrupted、InterruptedException
  10. 长达1.5年华强北耳机微妙体验
  11. linux与hadoop常用命令梳理
  12. 算法学习之“Big Oh Notation”
  13. 【推荐】Java自学网站HOW2J.CN 手把手带你做实践项目
  14. ubuntu有怪怪的声音一直跟读屏幕解决方法
  15. 洛谷 1417 烹调方案
  16. MT40A1G8SA-062E AAT:E内存颗粒D9XSP芯片
  17. 四川省部分地区经济发展水平的统计分析
  18. 一定能看懂的超详细分离变量法过程
  19. 苹果讨好中国的这十年
  20. Oracle问题之ORA-12560TNS:协议适配器错误-转载

热门文章

  1. Flutter 十六进制颜色转换
  2. workman 日志_workerman
  3. utf8编码和utf8mb4编码(其它编码简介)
  4. git回退到上一个版本:
  5. 五百亿!又一大型平台崩了!85后女老板跑路!
  6. 【论文阅读】3D Topology-Preserving Segmentation with Compound Multi-Slice Representation
  7. 【电脑桌面不见了怎么办】
  8. BZOJ4167: 永远亭的竹笋采摘 分块
  9. 启用Win10家庭版的远程桌面服务端
  10. 虚拟IP人物,同时空出现——思念党的福音