第2章Android生命周期与组件通信_第1页
第2章Android生命周期与组件通信_第2页
第2章Android生命周期与组件通信_第3页
第2章Android生命周期与组件通信_第4页
第2章Android生命周期与组件通信_第5页
已阅读5页,还剩80页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章Android生命周期与组件通信1主要内容2.1Android生命周期2.2Activity组件2.3Intent信使22.1Android生命周期程序的生命周期程序的生命周期是在Android系统中进程从启动到终止的所有阶段,也就是Android程序启动到停止的全过程。程序的生命周期由Android系统进行调度和控制的。Android系统中的进程优先级由高到低前台进程可见进程服务进程后台进程空进程3前台进程前台进程是Android系统中最重要的进程,是与用户正在交互的进程,包含以下四种情况。进程中的Activity正在与用户进行交互。进程服务被Activity调用,而且这个Activity正在与用户进行交互。进程服务正在执行声明周期中的回调函数,如onCreate()、onStart()或onDestroy()。进程的BroadcastReceiver正在执行onReceive()函数。Android系统在多个前台进程同时运行时,可能会出现资源不足的情况,此时会清除部分前台进程,保证主要的用户界面能够及时响应。2.1Android生命周期4可见进程可见进程指部分程序界面能够被用户看见,却不在前台与用户交互,不响应界面事件的进程。如果一个进程包含服务,且这个服务正在被用户可见的Activity调用,此进程同样被视为可见进程。Android系统一般存在少量的可见进程,只有在特殊的情况下,Android系统才会为保证前台进程的资源而清除可见进程。2.1Android生命周期5服务进程服务进程是指包含已启动服务的进程没有用户界面在后台长期运行Android系统除非不能保证前台进程或可视进程所必要的资源,否则不强行清除服务进程后台进程后台进程是指不包含任何已经启动的服务,而且没有任何用户可见的Activity的进程Android系统中一般存在数量较多的后台进程,在系统资源紧张时,系统将优先清除用户较长时间没有见到的后台进程2.1Android生命周期6空进程空进程是不包含任何活跃组件的进程空进程在系统资源紧张时会被首先清除但为了提高Android系统应用程序的启动速度,Android系统会将空进程保存在系统内存用,在用户重新启动该程序时,空进程会被重新使用除了以上的优先级外,以下两方面也决定他们的优先级进程的优先级取决于所有组件中的优先级最高的部分进程的优先级会根据与其他进程的依赖关系而变化2.1Android生命周期72.2Activity组件

2.2.1Android组件简介2.2.2Activity生命周期2.2.3Task与Activity栈2.2.4Activity基本状态82.2.1Android组件简介组件是可以调用的基本功能模块,Android应用程序就是由组件组成的。Android系统有四个重要的组件,分别是Activity、Service、BroadcastReceiver和ContentProvider。ActivityActivity是Android程序的呈现层,显示可视化的用户界面,并接收与用户交互所产生的界面事件。Android应用程序可以包含一个或多个Activity,一般在程序启动后会呈现一个Activity,用于提示用户程序已经正常启动。在界面上的表现形式:全屏窗体,非全屏悬浮窗体,对话框。ServiceService用于没有用户界面,但需要长时间在后台运行的应用。92.2.1Android组件简介BroadcastReceiverBroadcastReceiver是用来接受并响应广播消息的组件。不包含任何用户界面。可以通过启动Activity或者Notification通知用户接收到重要信息。Notification能够通过多种方法提示用户,包括闪动背景灯、震动设备、发出声音或在状态栏上放置一个持久的图标。ContentProviderContentProvider是Android系统提供的一种标准的共享数据的机制,应用程序可以通过ContentProvider访问其他应用程序的私有数据。私有数据可以是存储在文件系统中的文件,也可以是SQLite中的数据库。Android系统内部也提供一些内置的ContentProvider,能够为应用程序提供重要的数据信息。102.2.2Activity生命周期Activity生命周期Activity生命周期指Activity从启动到销毁的过程。Activity表现为四种状态,分别是活动状态、暂停状态、停止状态和非活动状态。活动状态,Activity在用户界面中处于最上层,完全能用户看到,能够与用户进行交互。暂停状态,Activity在界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互。停止状态,Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡。非活动状态不在以上三种状态中的Activity则处于非活动状态。112.2.2Activity生命周期Activity的四种状态的变换关系图12举例:建立一个新的Android工程工程名称:Chp02_NewActivity包名称:com.NewActivityActivity名称:NewActivity132.2.2

Activity生命周期NewActivity.java文件的代码1packagecom.NewActivity;23importandroid.app.Activity;4importandroid.os.Bundle;5importandroid.widget.Button;6importandroid.widget.TextView;78publicclassNewActivityextendsActivity{9 privateTextViewm_txtNewAct=null;10 privateButtonm_btnNewAct=null;11/**Calledwhentheactivityisfirstcreated.*/12@Override13publicvoidonCreate(BundlesavedInstanceState){14super.onCreate(savedInstanceState);15setContentView(R.layout.main);16this.m_btnNewAct=(Button)findViewById(R.id.btnNewAct);17this.m_txtNewAct=(TextView)findViewById(R.id.txtNewAct);18this.m_txtNewAct.setText("文本控件");19this.m_btnNewAct.setText("按钮控件");142.2.2

Activity生命周期NewActivity.java文件的代码从代码第8行可以看出,一个Activity就是一个Java类,而且必须继承自Activity基类。代码第13行复写了基类的onCreate()方法,并且在14行调用了父类的onCreate()方法,这在创建Activity时同样是必须的,在Activity第一次运行时总会首先执行onCreate()方法,此方法作用类似于其它面向对象语言中的构造函数。代码15行采用setContentView()方法设置布局文件,代码16和17行的findViewById()方法功能是通过控件ID属性获得所需的控件对象,此方法返回View类,View类是android系统的控件基类,可以通过强制类型转换转化成所需的控件对象。代码18行和19行完成相应控件显示文本的设置。20.}21.}15AndroidManifest.xml文件中声明Activity的代码如下:2.2.2

Activity生命周期……1<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">2<activityandroid:name=".NewActivity"3android:label="@string/app_name">4<intent-filter>5<actionandroid:name="ent.action.MAIN"/>6<categoryandroid:name="ent.category.LAUNCHER"/>7</intent-filter>8</activity>9</application>……162.2.2

Activity生命周期在应用程序application元素中声明了前面所定义的Activity,在application元素中同样可以声明Service、BroadcastReceiver和ContentProvider。代码第2行属性android:name定义了实现Activity类的名称,其值有两种实现形式,一种是使用全称com.NewActivity,另外一种是使用简化后的类名称.NewActivity,其中的“.”不可省略。第3行属性android:label定义了Activity的标签名称,此名称将在Activity界面上面以标题形式显示,@string/app_name是一种资源引用方式,其真实值是res/values/string.xml文件中app_name元素代表的字符串值。intent-filter元素中包含了两个子元素action和category,这些元素的意义将在后面详细介绍,在这里intent-filter的功能就是设置程序的启动主窗体为包含它的Activity。172.2.2

Activity生命周期在创建的Activity上可以按照需要布局必要的界面控件,如上面的Activity上添加了一个按钮(Button)和一个文本框(TextView),其声明的代码如下所示:……1<TextView2android:layout_width="fill_parent"3android:layout_height="wrap_content"4android:id="@+id/txtNewAct"5/>6<Button7android:layout_width="fill_parent"8android:layout_height="wrap_content"9android:id="@+id/btnNewAct"10/>……182.2.2

Activity生命周期属性android:layout_width定义控件横向宽度,属性android:layout_height定义控件纵向高度,属性android:layout_width和属性android:layout_height的可选值均为fill_parent与wrap_content。fill_parent值代表填充父控件,wrap_content值代表按照内容填充。属性android:id定义控件唯一标识名称,“@+id”告诉系统在R.java文件中生成相应的值。在生命周期中起重要作用的是它的事件回调函数。Activity提供了七个生命周期的事件回调函数,在这些事件回调函数中添加相应的功能代码可以实现或者完成相应的功能。192.2.2Activity生命周期事件的回调函数publicclassMyActivityextendsActivity{protectedvoidonCreate(BundlesavedInstanceState);protectedvoidonStart();protectedvoidonRestart();protectedvoidonResume();protectedvoidonPause();protectedvoidonStop();protectedvoidonDestroy();}202.2.2Activity生命周期Activity生命周期的事件回调函数函数是否

可终止说明onCreate()否Activity启动后第一个被调用的函数,常用来进行Activity的初始化,例如创建View、绑定数据或恢复信息等。onStart()否当Activity显示在屏幕上时,该函数被调用。onRestart()否当Activity从停止状态进入活动状态前,调用该函数。onResume()否当Activity能够与用户交互,接受用户输入时,该函数被调用。此时的Activity位于Activity栈的栈顶。onPause()是当Activity进入暂停状态时,该函数被调用。一般用来保存持久的数据或释放占用的资源。onStop()是当Activity进入停止状态时,该函数被调用。onDestroy()是在Activity被终止前,即进入非活动状态前,该函数被调用。212.2.2Activity生命周期Activity状态保存/恢复的事件回调函数函数是否

可终止说明onSaveInstanceState()否Android系统因资源不足终止Activity前调用该函数,用以保存Activity的状态信息,供onRestoreInstanceState()或onCreate()恢复之用。onRestoreInstanceState()否恢复onSaveInstanceState()保存的Activity状态信息,在onStart()和onResume()之间被调用。22Activity事件回调函数的调用顺序232.2.2

Activity生命周期全生命周期函数的调用顺序:onCreate()→onStart()→onResume()→onPause()→onStop()→onDestroy()调用onCreate()函数分配资源调用onStart()将Activity显示在屏幕上调用onResume()获取屏幕焦点调用onPause()、onStop()和onDestroy(),释放资源并销毁进程242.2.2

Activity生命周期全生命周期运行程序,启动MainActivity完成后,查看日志过滤器中的System.out信息如图2.2.2(a)。如果此时再按下模拟器的返回键,则相当于关闭了MainActivity,日志过滤器中的System.out信息变成了如图2.2.2(b)。图2.2.2(a)MainActivity启动日志图2.2.2(b)MainActivity全生命周期日志252.2.2

Activity生命周期可视生命周期可视生存期(VisibleLifetime)是指从调用onStart()开始到调用onStop()结束之间的周期阶段。在这段时间里,Activity对用户是可见的,但是它有可能不是用户所关注的Activity,或者它可能被部分遮挡了。当Activity界面不可见的时候更新它是没有意义的,因为这样子消耗了资源却没有起到实际的作用。当Activity界面再次可见的时候,可以使用onStart()或者onRestart()来恢复或者重启这些进程。onRestart()方法在onStart()方法前被调用,用于Activity从不可见变为可见的过程,进行特定处理。Activity经常在可见和不可见的状态多次转换,所以onStart()和onStop()多次被调用。另外,onStart()和onStop()同样也用于注册和销毁BroadcastReceive。262.2.2

Activity生命周期可视生命周期函数的调用顺序:

onSaveInstanceState()→onPause()→onStop()→onRestart()→onStart()→onResume()调用onSaveInstanceState()函数保存Activity状态调用onPause()和onStop(),停止对不可见Activity的更新调用onRestart()恢复需要界面上需要更新的信息调用onStart()和onResume()重新显示Activity,并接受用户交互272.2.2

Activity生命周期活动生命周期活动生存期(ForegroundLifetime)指调用onResume()及其对应的onPause()之间的那段生存期,此时,Activity在屏幕的最上层,能够与用户直接交互。在活动生存期内可以安全的假设onSaveInstanceState()和onPause()会被调用,大部分Activity至少需重写onPause()方法来提交未保存的改动,因为在onPause()之外Activity可能在没有任何警告的情况下被终止。在Activity不在前台的时候也可以根据应用程序的架构,选择挂起线程、进程或者广播接收器。onResume()方法可以是轻量级的,因为要求加载Activity界面的时候可以由onCreate()和onRestoreIntanceState()方法处理。使用onResume()可以重新注册已经使用onPause()停止的广播接收器或者其他进程。onPause()最好也是轻量级的,因为下一个要显示到前台的activity的onRsume()要等当前activity的onPause返回后才执行。所以,尽量让onPause()方法中的代码执行迅速,让onResume()方法中的代码尽可能少,以保证在前台和后台之间进行切换的时候程序能够保持响应。282.2.2

Activity生命周期活动生命周期函数调用顺序如下:onSaveInstanceState()→onPause()→onResume()调用onSaveInstanceState()保存Activity的状态调用onPause()停止与用户交互调用onResume()恢复与用户的交互29举例:建立一个新的Android工程工程名称:Chp02_ActivityLife包名称:com.NewActivityActivity名称:NewActivity302.2.2

Activity生命周期MainActivity.java文件的代码……1//主窗体2publicclassMainActivityextendsActivity{3 privateButtonm_btnMainAct=null;4 privateTextViewm_txtMainAct=null;5/**Calledwhentheactivityisfirstcreated.*/6@Override7publicvoidonCreate(BundlesavedInstanceState){8System.out.println("MainActivity-onCreate");9 super.onCreate(savedInstanceState);10setContentView(R.layout.main);11m_btnMainAct=(Button)findViewById(R.id.btnMainAct);12m_txtMainAct=(TextView)findViewById(R.id.txtMainAct);13m_btnMainAct.setOnClickListener(newButtonListener());14m_btnMainAct.setText("启动SecondActivity");15m_txtMainAct.setText("这是MainActivity");16}17 @Override18 protectedvoidonDestroy(){19 //TODOAuto-generatedmethodstub312.2.2

Activity生命周期MainActivity.java文件的代码20 System.out.println("MainActivity-onDestroy");21 super.onDestroy();22 }23 @Override24 protectedvoidonPause(){25 //TODOAuto-generatedmethodstub26 System.out.println("MainActivity-onPause");27 super.onPause();28 }29 @Override30 protectedvoidonRestart(){31 //TODOAuto-generatedmethodstub32 System.out.println("MainActivity-onRestart");33 super.onRestart();34 }35 @Override36 protectedvoidonResume(){37 //TODOAuto-generatedmethodstub322.2.2

Activity生命周期MainActivity.java文件的代码38 System.out.println("MainActivity-onResume");39 super.onResume();40 }41 @Override42 protectedvoidonStart(){43 //TODOAuto-generatedmethodstub44 System.out.println("MainActivity-onStart");45 super.onStart();46 }47 @Override48 protectedvoidonStop(){49 //TODOAuto-generatedmethodstub50 System.out.println("MainActivity-onStop");51 super.onStop();52 }332.2.2

Activity生命周期NewActivity.java文件的代码

MainActivity是主窗体类,此类中重写了Activity的七个生命周期回调函数,并均使用方法System.out.println(),此方法向控制台输出相应信息并换行。代码53行通过内部类实现按钮点击监听器。代码56-58行,通过Intent实现不同Activity的交互,Intent会在后面的内容中详细介绍。ButtonListener类实现的功能是按钮点击后的响应,即启动另一个Activity。53 classButtonListenerimplementsOnClickListener{54 @Override55 publicvoidonClick(Viewv){ 56 Intentintent=newIntent(); 57 intent.setClass(MainActivity.this,SecondActivity.class); 58 MainActivity.this.startActivity(intent);59 }60 }61}342.2.2

Activity生命周期SecondActivity.java代码文件1//第二屏2publicclassSecondActivityextendsActivity{3 privateButtonm_btnSecondAct=null;4 privateTextViewm_txtSecondAct=null;5 /**Calledwhentheactivityisfirstcreated.*/6@Override7publicvoidonCreate(BundlesavedInstanceState){8 System.out.println("SecondActivity-onCreate");9super.onCreate(savedInstanceState);10setContentView(R.layout.second);11m_btnSecondAct=(Button)findViewById(R.id.btnSecondAct);12m_txtSecondAct=(TextView)findViewById(R.id.txtSecondAct);13m_btnSecondAct.setOnClickListener(newButtonListener());14m_btnSecondAct.setText("返回MianActivity");15m_txtSecondAct.setText("这是SecondActivity");16}17 @Override18 protectedvoidonDestroy(){19 //TODOAuto-generatedmethodstub352.2.2

Activity生命周期SecondActivity.java文件的代码20 System.out.println("SecondActivity-onDestroy");21 super.onDestroy();22 }23 @Override24 protectedvoidonPause(){25 //TODOAuto-generatedmethodstub26 System.out.println("SecondActivity-onPause");27 super.onPause();28 }29 @Override30protectedvoidonRestart(){31 //TODOAuto-generatedmethodstub32 System.out.println("SecondActivity-onRestart");33 super.onRestart();34 }35 @Override36 protectedvoidonResume(){37 //TODOAuto-generatedmethodstub362.2.2

Activity生命周期MainActivity.java文件的代码38 System.out.println("SecondActivity-onResume");39 super.onResume();40 }41 @Override42protectedvoidonStart(){43 //TODOAuto-generatedmethodstub44 System.out.println("SecondActivity-onStart");45 super.onStart();46 }47 @Override48 protectedvoidonStop(){49 //TODOAuto-generatedmethodstub50 System.out.println("SecondActivity-onStop");51 super.onStop();52 }372.2.2

Activity生命周期NewActivity.java文件的代码

通过查看日志信息可以跟踪上面代码的运行情况。在Eclipse中切换到DDMS界面,其中的LogCat用于显示系统日志信息,能够捕获的信息包括Dalvik虚拟机产生的信息、进程信息、ActivityManager信息、PackagerManager信息、Homeloader信息、WindowsManager信息、Android运行时信息和应用程序信息等。通过在LogCat中添加日志过滤器可以跟踪查看System.out输出信息。53 classButtonListenerimplementsOnClickListener{54 @Override55 publicvoidonClick(Viewv){ 56 Intentintent=newIntent(); 57 intent.setClass(SecondActivity.this,MainActivity.class); 58 SecondActivity.this.startActivity(intent);59 }60}61}382.2.2

Activity生命周期MainActivity调用SecondActivity日志重新运行上面的工程,MainActivity启动完成后,System.out信息同图2.2.2(a),此时点击上面的按钮启动SecondActivity,查看System.out信息,如图2.2.3所示。从图中可以看出,前三行信息是MainActivity的启动日志,后面五行是MainActivity中启动SecondActivity的日志。SecondActivity的启动过程中,首先调用MainActivity的onPause()方法,再依次调用SecondActivity的onCreate()、onStart()和onResume(),最后调用MainActivity的onStop()方法,此时SecondActivity完全遮盖MainActivity。392.2.2

Activity生命周期从SecondActivity返回到MainActivity日志此过程中首先调用SecondActivity的onPause()方法,接着调用MainActivity的onRestart()、onStart()和onResume方法,由于是返回键返回,此时SecondActivity被销毁,依次调用了onStop()和onDestroy()方法。402.2.2

Activity生命周期点击按钮SecondActivity返回到MainActivity此过程中首先调用SecondActivity的onPause()方法,接着调用MainActivity的onCreate()、onStart()和onResume方法,最后调用了SecondActivity的onStop()方法。比较图2.2.4,此时的MainActivity被全新重建,与此同时SecondActivity也并没有被销毁,其资源仍占据着系统资源。412.2.2

Activity生命周期部分遮挡的情况AndroidManifest.xml文件中为SecondActivity添加属性android:theme并且设置其值为android:theme="@android:style/Theme.Dialog"。此属性定义SecondActivity显示方式为窗口而不是整个屏幕。运行程序并从MainActivity中启动SecondActivity,此过程System.out输出信息如图2.2.6所示。比较图2.2.3,可以看出,部分遮挡的情况下,MainActivity不会调用自身的onStop()方法,这是因为MainActivity仍可见,只是不能直接和用户交互。422.2.2

Activity生命周期Activity的生命周期中还需注意以下几点:当Activity处于暂停或停止状态下,操作系统内存缺乏可能会销毁Activity,或者其他意外突发情况,Activity被操作系统销毁,内存回收时onSaveInstanceState()会被调用,但是当用户主动销毁一个Activity时(例如,按返回键)onSaveInstanceState()就不会被调用。onSaveInstanceState()适合保存一些临时性的数据,onPause()适合保存一些持久化的数据onRestoreInstanceState()是在onStart()和onCreate()之间执行用户恢复ActivityUI状态。如果数据比较重要但是数据任在运算当中,则应该缓存他们,如果运算结束并且得到了结果,则应该对其进行持久化操作。只要Activity被覆盖一定会调用onPause()方法,只要Activity重新回到前台一定会调用onResume()方法。432.2.3Task与Activity栈一个Task是用户可以完成一个特定目标的一组Activity,与Activity属于哪个Application无关。除非明确地新建一个Task,否则用户启动的所有Activity都默认是当前Task的一部分。这些Activity可能属于任何一个Application,属于同一个Application或者属于不同的Application。例如,从联系人列表(第一个Activity)开始,然后选择一个邮箱地址(第二个Activity),然后附加一个照片(第三个Activity),联系人列表、邮箱和图片,这些都存在于不同的Activity中,但却属于同一个Task。442.2.3Task与Activity栈启动Task的Activity被称作根Activity。通常,Task是从应用管理器、主屏或者最近的Task(长按HOME键)开始的。用户可以通过点击根Activity的图标回到Task里去,就像启动这个Activity一样。在这个Task中,使用BACK键可以回到这个Task的前一个Activity里,Activity栈可以由一个或多个Task组成。452.2.3Task与Activity栈Task的一个重要的特性就是,用户可以中断其当前正在进行的任务,去进行另一个Task,然后可以返回到原来的那个Task去完成它,即打断Task。这个特性的目的,就是用户可以同时运行多个任务,并且可以在这些任务间切换。有两种主要的的情形离开一个Task:其一是用户被Notification打断,例如来了一个通知,用户开始关注处理这个通知。其二是用户决定开始另一个任务,例如用户按了HOME键,然后开始了另一个Application。遇到这两种情况时,应该注意能让用户返回到离开的那个任务。462.2.3Task与Activity栈当用户在Application中,从一个Activity跳到另一个时Activity,Android系统会保存一个用户访问Activity的线性导航历史,这就是activity栈,也被称为返回栈。一般来说,当用户运行一个新的Activity,这个Activity就会被加到Activity栈里。因此,当用户按BACK键的时候,栈中的上一个Activity就会被展示出来,用户可以一直按BACK键,直到返回到了主屏Activity。把Activity加入到当前栈里的操作,与Activity是否启动了一个新Task无关,但是返回操作可以使用户从当前Task回到上一个Task。用户可以在应用管理器、主屏、或者“最近Task”屏幕,恢复到刚刚的Task。472.2.3Task与Activity栈只有Activity可以加到Activity栈里去,

View、Window、Menu或者Dialog都能进行此种操作。假设界面A跳到界面B,然后用户可以用BACK跳回界面A。这种情况下,界面A和界面B都要被实现成Activity。这个规则有一个例外的情况,那就是除非其应用控制了BACK键并且自行管理界面导航。下面通过图示介绍多个Activity互相调用时Activity栈的变化。如图2.2.7所示,假设一个Application中包含四个Activity,为Activity1~Activity4。应用程序启动之后,运行第一个Activity1,Activity1对象被压入到Stack当中。在Activity1中启动第二个Activity2,

Activity2对象被压入到Stack当中,由于手机显示的总是位于Stack顶部的Activity,所以此时用户看到的屏幕是Activity2。在Activity2中启动第三个Activity3,

Activity3对象被压入到Stack当中,用户看到的屏幕变成Activity3。在Activity3中启动最后一个Activity4,Activity4对象被压入到Stack当中,手机屏幕变成Activity4。点击BACK按钮,这时Activity4对象在栈中被弹出,第三个Activity置于栈顶,依次点击BACK按钮,最后可返回到主屏幕Activity1。482.2.3Task与Activity栈492.2.3Task与Activity栈Activity栈:遵循“后进先出”的规则502.2.4Activity基本状态Android系统中,Activity的四种基本状态:活动态(Active/Running):Activity在用户界面中处于最上层,完全能被用户看到,能够与用户进行交互。暂停态(Paused):Activity界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互。停止态(Stopped):Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡。非活动态(Killed):又称为死亡态,是指不在上面三种状态中之内的Activity状态。512.2.4Activity基本状态Activity四种基本状态的转关系及回调函数如下图所示522.3Intent信使

2.3.1Intent基本构成2.3.2Intent形式2.3.3IntentFilter2.3.4Activity信息传递53 Intent是一个动作的完整描述,包含了动作的产生组件、接收组件和传递的数据信息。Intent本身是一个对象,是一个被动的数据结构,该数据结构包含被执行动作的抽象描述,所以Intent也可称为一个在不同组件之间传递的消息,这个消息在到达接收组件后,接收组件会执行相关的动作。2.3Intent信使542.3.1Intent基本构成Intent对象抽象地描述了要执行的动作,其描述的基本内容分为六部分:组件名称(ComponentName)动作(Action)数据(Data)类别(Category)附加信息(Extra)标志(Flag)552.3.1Intent基本构成组件名称ComponentName组件名称是指Intent目标组件的名称,组件名称是一个ComponentName对象,这种对象名称是目标组件完全限定类名和目标组件所在应用程序的包名的组合。组件名字通过setComponent(),setClass()或setClassName()设置,通过getComponent()读取。动作Action:Action描述Intent所触发动作名字的字符串,对于BroadcastIntent来说,Action指被广播出去的动作。理论上Action可以为任何字符串,而与Android系统应用有关的Action字符串以静态字符串常量的形式定义在了Intent类中。常见动作见表156数据Data数据是描述Intent要操作的数据URI和数据MIME类型,不同的动作有不同的数据规格。匹配一个Intent到一个能够处理数据的组件,通常需要知道数据的类型(它的MIME类型)和它的URI。类别Category类别指定了将要执行Action的其他一些额外的信息,Android系统支持常见的类别字符串常量如表2所示。2.3.1Intent基本构成572.3.1Intent基本构成表1Android系统支持用于Activity组件的常见的动作字符串常量动作说明ACTION_ANSWER打开接听电话的Activity,默认为Android内置的拨号盘界面ACTION_CALL打开拨号盘界面并拨打电话,使用Uri中的数字部分作为电话号码ACTION_DELETE打开一个Activity,对所提供的数据进行删除操作ACTION_DIAL打开内置拨号盘界面,显示Uri中提供的电话号码ACTION_EDIT打开一个Activity,对所提供的数据进行编辑操作ACTION_INSERT打开一个Activity,在提供数据的当前位置插入新项ACTION_PICK启动一个子Activity,从提供的数据列表中选取一项ACTION_SEARCH启动一个Activity,执行搜索动作ACTION_SENDTO启动一个Activity,向数据提供的联系人发送信息ACTION_SEND启动一个可以发送数据的ActivityACTION_VIEW最常用的动作,对以Uri方式传送的数据,根据Uri协议部分以最佳方式启动相应的Activity进行处理。对于http:address将打开浏览器查看;对于tel:address将打开拨号呼叫指定的电话号码ACTION_WEB_SEARCH打开一个Activity,对提供的数据进行Web搜索582.3.1Intent基本构成表2Android系统支持常见的类别字符串常量值说明ALTERNATIVEIntent数据默认动作的一个可替换的执行方法SELECTED_ALTERNATIVE和ALTERNATIVE类似,但替换的执行方法不是指定的,而是被解析出来的BROWSABLE声明Activity可以由浏览器启动DEFAULT为Intent过滤器中定义的数据提供默认动作HOME设备启动后显示的第一个ActivityLAUNCHER在应用程序启动时首先被显示59附加信息Extra额外的附加信息,是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,当使用Intent连接不同的组件时,有时需要在Intent中附加额外的信息,以便将数据传递给目标Activity。Extra用键值对结构保存在Intent对象当中,Intent对象通过调用方法putExtras()和getExtras()来存储和获取Extra。在Intent类中同样为Android系统应用的一些Exrta的键值定义了静态的字符串常量,如下表所示。标记Flag指示Android系统如何去启动一个Activity和启动之后的处理。例如,活动应该属于那个任务,是否属于最近的活动列表。通常使用setFlags()方法和addFlags()方法设置和添加。2.3.1Intent基本构成60表3Android系统支持常见的Extra字符串常量值说明EXTRA_BCC装有邮件密送地址的字符串数组EXTRA_CC装有邮件抄送地址的字符串数组EXTRA_EMAIL装有邮件发送地址的字符串数组EXTRA_INTENT使用ACTION_PICK_ACTIVITY动作时装有Intent选项的键EXTRA_KEY_EVENT触发该Intent的按键的KeyEvent对象EXTRA_PHONE_NUMBER使用拨打电话相关的Action时,电话号码字符串的键,类型为StringEXTRA_SHORTCUT_ICON使用ACTION_CREATE_SHORTCUT在Activity创建快捷方式时,对快捷方式的描述信息。ICON和ICON_RESOURCE描述的是快捷方式的图标,类型分别为Bitmap和ShortcutIconResource。INTENT描述的是快捷方式相对应的Intent对象。NAME描述的是快捷方式的名字。EXTRA_SHORTCUT_ICON_RESOURCEEXTRA_SHORTCUT_INTENTEXTRA_SHORTCUT_NAMEEXTRA_SUBJECT描述信息主体的键EXTRA_TEXT使用ACTION_SEND动作时,用来描述要发送的文本信息,类型是ChatSequenceEXTRA_TITLE使用ACTION_CHOOSER动作时,描述对话框标题的键,类型是ChatSequenceEXTRA_UID使用ACTION_UID_REMOVED动作时,描述删除用户Id的键,类型为Int612.3.2Intent形式Android系统中有两种Intent形式,分别为显式Intent和隐式Intent。显式Intent(ExplicitIntents)指定了目标组件,一般调用setComponent()或者setClass(Context,Class)设定Intents的component属性,指定具体的组件类。这些Intent一般不包括包括其它任何信息,通常用于应用程序内部消息,如一个Activity启动从属的服务或启动另一个Activity。隐式Intent(ImplicitIntents)没有明确指明目标组件,经常用于启动其他应用程序中的组件。622.3.2Intent形式启动Activity显式启动使用Intent显式启动Activity创建一个Intent指定当前的应用程序上下文以及要启动的Activity把创建好的这个Intent作为参数传递给startActivity()方法Intentintent=newIntent(IntentDemo.this,ActivityToStart.class);startActivity(intent);63举例:建立一个新的Android工程工程名称:Chp02_IntentStartDirectlyActivity名称:MainActivity,SecondActivityIntent显式启动SecondActivity64AndroidManifest.xml文件中声明Activity的代码如下:……<applicationandroid:icon="@drawable/icon“android:label="@string/app_name">2<activityandroid:name=".MainActivity"3android:label="@string/app_name">4<intent-filter>5<actionandroid:name="ent.action.MAIN"/>6<categoryandroid:name="ent.category.LAUNCHER"/>7</intent-filter>8</activity>9<activityandroid:name=".SecondActivity"10android:label="@string/app_name">11</activity>12</application>……2.3.2Intent形式65MainActivity.java文件的代码……1publicclassMainActivityextendsActivity{2 privateButtonm_btnMainAct=null;3/**Calledwhentheactivityisfirstcreated.*/4@Override5publicvoidonCreate(BundlesavedInstanceState){6super.onCreate(savedInstanceState);7setContentView(R.layout.main);8m_btnMainAct=(Button)findViewById(R.id.btnMainAct);9m_btnMainAct.setOnClickListener(newOnClickListener(){10publicvoidonClick(Viewview){11 //声明一个Intent对象12 IntentinttMainAct=newIntent(MainActivity.this,SecondActivity.class);13 //Intent显示启动Activity14 startActivity(inttMainAct);15 }16});17}18}……662.3.2Intent形式

代码12行采用了第五种构造函数形式,指明了主调组件MainActivity和目标组件SecondActivity。startActivity()方法启动Intent指向的Activity。上面代码使用了Activity显示启动的方式,直接指明了需要启动的Activity。Intent类定义了六种构造函数。Intent();Intent(Intento);Intent(Stringaction);Intent(Stringaction,Uriuri);Intent(ContextpackageContext,Class<?>cls);Intent(Stringaction,Uriuri,ContextpackageContext,Class<?>cls);第一种为空构造函数,调用此构造函数的Intent为一个空Intent对象。第二种的参数也是一个Intent对象,通过复制该对象初始化新的Intent对象。第三种构造函数指定了动作Action的类型,第四种构造函数有两个参数分别为指定了动作Action和UriData。第五种构造函数指定了主调组件和目标组件。第六种构造函数拥有三个参数,描述了动作Action、数据Data和目标组件。67启动Activity隐式启动优点:不需要指明需要启动哪一个Activity,而由Android系统来决定,有利于使用第三方组件隐式启动Activity时,Android系统在应用程序运行时解析Intent,并根据一定的规则对Intent和Activity进行匹配,使Intent上的动作、数据与Activity完全吻合匹配的Activity可以是应用程序本身的,也可以是Android系统内置的,还可以是第三方应用程序提供的。因此,这种方式更加强调了Android应用程序中组件的可复用性682.3.2Intent形式

下面代码为隐式启动Activity的Intent示例。IntentinttMainAct=newIntent(Intent.ACTION_VIEW,Uri.parse(“”));startActivity(inttMainAct);Intent的动作是Intent.ACTION_VIEW,根据URI的数据类型来匹配动作。数据部分的URI是Web地址,使用Uri.parse(urlString)方法,可以简单的把一个字符串解释成Uri对象。显然Intent构造函数采用的是第四种格式,此代码的意义就是隐式调用系统内部的Web浏览器,打开网址。692.3.3IntentFilterIntent-Filter,即Intent过滤器,是Android系统提供的一种机制,根据Intent中的动作Action、类别Categorie和数据Data等内容,对适合接收该Intent的组件进行匹配和筛选,用于隐式启动组件过程中。Android应用程序中Activity组件、Service组件和BroadcastReceiver都可以注册Intent过滤器,可以注册一个也可以注册多个。组件注册Intent过滤器常见的方法是在AndroidManifest.xml文件中用节点<Intent-Filter>描述。70IntentFilter所支持的属性2.3.3IntentFilter标签属性说明<action>android:name指定组件所能响应的动作,用字符串表示,通常使用Java类名和包的完全限定名构成<category>android:category指定以何种方式去服务Intent请求的动作<data>android:host指定一个有效的主机名android:mimetype指定组件能处理的数据类型android:path有效的URI路径名android:port主机的有效端口号android:scheme所需要的特定的协议71Android系统中Intent过滤器的匹配规则可以概括成以下四点:Android系统把所有应用程序包中的Intent过滤器集合在一起,形成一个完整的Intent过滤器列表.在Intent与Intent过滤器进行匹配时,Android系统会将列表中所有Intent过滤器的动作和类别与Intent进行匹配,任何不匹配的Intent过滤器都将被过滤掉。2.3.3IntentFilter72把Intent数据Uri的每个子部与Intent过滤器的<data>标签中的属性进行匹配,如果<data>标签指定了协议、主机名、路径名或MIME类型,那么这些属性都要与Intent的Uri数据部分进行匹配,任何不匹配的Intent过滤器均被过滤掉。如果Intent过滤器的匹配结果多于一个,则可以根据在<intent-filter>标签中定义的优先级标签来对Intent过滤器进行排序,优先级最高的Intent过滤器将被选择。2.3.3IntentFilter732.3.4Activity信息传递在开发Android应用程序过程中,Activity之间进行信息传递不可避免。Activity之间信息传递最常见的情形有两种,一种是获取子Activity返回值,另一种传递消息给子Activity。下面通过一个例子具体实现上述两种Activity之间进行信息传递的情形。建立工程NeuChp02_IntentExchangeMessage,实现三个Activity,分别为MainActivity、SecondActivity和ThirdActivity,其中MainActivity为父Activity,获取SecondActivity的返回值,传递信息给ThirdActivity74MainActivity.java文件代码如下:2.3.4Activity信息传递1publicclassMainActivityextendsActivity{2 privateButtonm_btnGetActReturnMainAct=null;3 privateButtonm_btnBroadCastMainAct=null;4 privateEditTextm_etxtGetActReturnMainAct=null;5 privateEditTextm_etxtBroadCastMainAct=null;6 privatestaticfinalintINFORMATIONACT=1;7/**Calledwhentheactivityisfirstcreated.*/8@Override9publicvoidonCreate(BundlesavedInstanceState){10super.onCreate(savedInstanceState);11setContentView(R.layout.main);12m_btnGetActReturnMainAct=(Button)findViewById(R.id.btnGetActReturnMainAct);13m_btnBroadCastMainAct=(Button)findViewById(R.id.btnBroadCastMainAct);14m_etxtGetActReturnMainAct=(EditText)findViewById(R.id.etxtGetActReturnMainAct);15m_etxtBroadCastMainAct=(EditText)findViewById(R.id.etxtBroadCastMainAct);16m_btnGetActReturnMainAct.setOnClickListener(newOnClickListener(){17publicvoidonClick(Viewview){18 //获取Activity返回值启动SecondActivity19 IntentinttMainAct=newIntent(MainActivity.this,SecondActivity.class);20 startActivityForResult(inttMainAct,INFORMATIONACT);21}22});23m_btnBroadCastMainAct.setOnClickListener(newOnClickListener(){24publicvoidonClick(Viewview){25 //传递信息值752.3.4Activity信息传递26 IntentinttMainAct=newIntent(MainActivity.this,ThirdActivity.class);27 St

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论