androidActivity详解.docx
- 文档编号:9361525
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:15
- 大小:114.77KB
androidActivity详解.docx
《androidActivity详解.docx》由会员分享,可在线阅读,更多相关《androidActivity详解.docx(15页珍藏版)》请在冰点文库上搜索。
androidActivity详解
Activity详解
1.什么是Activity?
Activity是一个应用程序组件,代表用来与用户进行交互的界面.比如,发邮件,拍照等的交互界面.一个应用程序通常由多个Activity松耦合的组成,典型的,当用户启动一个应用程序时见到的第一个交互界面(Activity)就叫做主Activity.当然,为了完成相应的动作,一个Activity可以启动另一个Activity;比如qq登陆界面,填写信息之后,发送一个信息去验证,通过之后就启动主界面Activity.每当启动一个新的Activity,前一个Activity将停止,但是系统将仍然保存这个对象在后台栈(backstack)里面。
当启动一个新的Activity,它将被放入backstack中,并且获得用户焦点。
Backstack遵循后进先出原则,所以当用户按手机上的back按钮时,当前的activity将会从backstack中移除,前一个Activity将被恢复。
(Backstack请参考TasksandBackStack文档)。
当然,Activity的创建,启动,恢复,暂停,停止,销毁都对应了一系列Activity的回调函数。
2.创建Activity。
创建一个Activity,需要继承Activity超类或继承自继承了Activity的子类。
在你实现的子类中,你需要实现由系统在Activity状态发生变化时调用的各个回调函数。
例如创建,暂停,停止等时会由系统调用对应的方法。
这里介绍两个很重要的方法:
onCreate():
这个方法是必须实现的。
当在创建一个Activity时候由系统调用。
在该方法里面,你应当初始化一些组件;最重要的是,你必须设置setContentView()方法来设置activity布局。
onPause():
当你离开该activity时将被调用,在这个方法里你可以保存一些信息到数据库或文件等。
一.实现用户界面。
用户交互界面(Activity)由一系列由View衍生出来的类组成。
每个view都占据activity窗口的一个矩形区域,并能产生相应的事件。
比如button,当点击它可以产生点击事件等。
你可以使用android提供的现成的组件来设计和组织你的布局。
Widgets:
通过屏幕产生视觉和互动效果的元素,比如按钮,文本框之类。
Layouts:
是一类通过ViewGroup派生的视图组件用来为放置在其中的其它view提供一个唯一布局,比如线性布局,网格布局,相对布局等。
你也可以通过继承View和ViewGroup类或它们的子类来实现你自己的小部件和布局,并且把它们应用到自己的应用程序里的Activity里面。
以XML文件来定义布局和使用View元素是最常用的方式,这些XML文件存放在你的应用的res目录下。
通过这种方式,你可以把定义Activity的页面布局和Activity的行为分开来。
你可以把资源文件所对应的ID通过setContentView()方法来设置UI的布局。
当然,设置View元素与布局也可以在Activity代码里面创建。
用户自定义接口(View或ViewGroup),参考UserInterface文档。
二.在manifest文件中定义activity元素。
为了系统能够访问你的Activity,你必须在manifest文件中配置相对应于你Activity的activity元素,如下:
name=".ExampleActivity"/> ... ... 三.使用intentfilters 在manifest文件中的activity元素可以通过 它的作用是为了使其它应用程序(包括自身)组件可以访问该activity。 假如你用AndroidSDK来创建你的android项目的话,你在manifest文件中可以看到一个intent-filter包含了一个响应的动作action和存放的类别category。 文件如下所示: name=".ExampleActivity"android: icon="@drawable/app_icon"> name="android.intent.action.MAIN"/> name="android.intent.category.LAUNCHER"/> --------------------------① Tip: 通过上述表述,即如果你的应用程序都是由自己应用程序内的Activity访问或不允许外部应用访问你的Activity,那么就不需要配置这些多余的intent-filter(当然,如上所示的①处代码是必不可少的,因为系统至少要有一个入口点才可以启动你的程序)。 然而,如果你想隐式的启动Activity或别的应用程序访问你的Activity,那么你必须增加额外的intent-filter。 想要了解更多的IntentorIntent-filter,参考文档IntentsandIntentFilters。 3.启动Activity。 通过startActivity(Intentintent)方法启动。 Intent对象可以精确指定你要启动的Activity或者描述你要启动Activity的类型。 当然Intent还可以传递少量的额外数据。 一: 当你仅设计在应用程序内访问Activity时,那么启动的方式如下,比如现在你要启动一个名叫SignInActivity的Activity。 Intentintent=newIntent(this,SignInActivity.class); startActivity(intent); 二: 然而,当你的应用程序需要用到例如发邮件,写短信等功能时,但是你的应用程序本身不具备这个功能,所以,你可能会用到含有该功能的在该手机上的其他应用程序的Activity,那么此时就体现了intent的价值,你只要创建一个Intent,描述Intent想要执行的动作,那么系统就会自动去匹配该动作的Activity并启动之。 Intentintent=newIntent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL,recipientArray); startActivity(intent); 三: 启动Activity并取得结果返回 有时候你想接收从你启动的Activity返回的信息,那么此时就应当使用startActivityForResult()来代替startActivity(),并且在接收返回信息的Activity里面重载onActivityResult()方法,该方法将接收并处理返回的信息。 privatevoidpickContact(){ //Createanintentto"pick"acontact,asdefinedbythecontentproviderURI Intentintent=newIntent(Intent.ACTION_PICK,Contacts.CONTENT_URI); startActivityForResult(intent,PICK_CONTACT_REQUEST); } @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ //Iftherequestwentwell(OK)andtherequestwasPICK_CONTACT_REQUEST if(resultCode==Activity.RESULT_OK&&requestCode==PICK_CONTACT_REQUEST){ //Performaquerytothecontact'scontentproviderforthecontact'sname Cursorcursor=getContentResolver().query(data.getData(), newString[]{Contacts.DISPLAY_NAME},null,null,null); if(cursor.moveToFirst()){//Trueifthecursorisnotempty intcolumnIndex=cursor.getColumnIndex(Contacts.DISPLAY_NAME); Stringname=cursor.getString(columnIndex); //Dosomethingwiththeselectedcontact'sname... } } } 这个例子表述了你接收返回信息的基本逻辑。 首先判断请求是否成功,如果成功的话,resultCode将被赋值为RESULT_OK,并且requestCode将与你在startActivityForResult(intent,PICK_CONTACT_REQUEST)方法里面的code相同,即同为PICK_CONTACT_REQUEST,如果都成立,那么你可以通过返回的Intent对象做相应的操作。 Tip: ContentResolver参考ContentProviders文档。 更多Intent信息参考IntentsandIntentFilters文档。 4.关闭Activity 通过Activity的finish()方法来关闭本Activity;若是通过startActivityForResult(Intentintent,intrequestCode)启动的Activity,那么可以通过finishActivity(intrequestCode)来关闭。 TIP: 请慎用finish()方法,Activity的生命周期是由系统来维持和管理的,如果你调用了该方法,可能有会影响用户体验,比如按手机的back按钮将跳到上上个页面去。 所以,除非你肯定的不希望用户再次返回到该Activity才使用。 5.管理Activity的生命周期 通过实现Activity的回调方法来管理你的Activity是开发一个健壮和灵活应用程序的至关重要的条件。 一个Activity的生命周期直接受与它关联的其他Activity以及进程和backstack影响。 Activity的存在可以划分为三种情况: 一: Resumed(运行状态的): 即当前屏幕可见视图代表的Activity,可以获取用户焦点。 二: Paused(暂停状态的): 在当前Activity前端有一个Resumed状态的Activity,但是Resumed状态的Activity部分覆盖当前Activity;在这个状态下当前Activity是存活的。 Paused状态的Activity当系统内存不足时有可能被杀死掉。 三: Stopped(已停止状态的): 该Activity被一个Resumed状态的Activity完全覆盖掉;在这个状态下Activity是存活的。 当长时间没有访问和系统内存不足时有可能被杀死掉。 1.实现Activity生命周期内的回调函数 当一个Activity在上述Activity存在状态中切换时,将对应不同的回调方法。 下面该Activity类列出了基本的可重写的回调方法: publicclassExampleActivityextendsActivity{ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //Theactivityisbeingcreated. } @Override protectedvoidonStart(){ super.onStart(); //Theactivityisabouttobecomevisible. } @Override protectedvoidonResume(){ super.onResume(); //Theactivityhasbecomevisible(itisnow"resumed"). } @Override protectedvoidonPause(){ super.onPause(); //Anotheractivityistakingfocus(thisactivityisabouttobe"paused"). } @Override protectedvoidonStop(){ super.onStop(); //Theactivityisnolongervisible(itisnow"stopped") } @Override protectedvoidonDestroy(){ super.onDestroy(); //Theactivityisabouttobedestroyed. } } Tip: 当你在实现任意以上重写方法时,必须首先调用父类的该方法;如上面例子代码所示。 例如super.onDestroy(); 如上所示方法,定义了整个Activity的生命周期。 你可以通过实现这些方法来达到管理entirelifetime,visiblelifetime,foregroundlifetime三个嵌套循环的不同生命周期段的实现动作。 一: entirelifetime(整个生命周期) 从调用onCreate()方法开始,到调用onDestory()结束。 你应当在onCreate()方法里面定义全局状态,比如设置布局,开始一个后台下载线程。 在onDestory()方法里面释放资源,比如停止下载资源线程。 二: visiblelifetime(可见生命周期) 从调用onStart()方法开始,到调用onStop()结束。 在这个时间段内你可以在屏幕上看到该Activity并与之交互。 你可以在onStart()方法里面注册一个BroadcastReceiver对象来监听正在显示的Activity发生改变时调用事件,而当这个Activity不再显示时将调用onStop()方法,在该方法里我们可以用来取消BroadcastReceiver对象的监听。 三: foregroundlifetime(可操作生命周期) 从调用onResume()方法开始,到调用onPause()结束。 在这段时间内,该Activity位于所有的其他Activity之上并且可以获得用户输入焦点。 一个Activity在这个时间段将会频繁的进入和淡出屏幕,比如当用户待机或弹出一个窗体的时候,将会调用onPause()方法,由于这操作比较频繁,所以在这个方法中一般做耗时较少的操作以确保用户体验流畅。 以下是Activity生命周期的图示: 下表更加详细的列出了Activity生命周期中各个方法的详细描述以及系统在调用相应方法后能否杀死对应的Activity。 方法 描述 Killableafter? 下一个调用的方法 onCreate() 在Activity第一次创建的时候调用。 在这个方法里你应当做所有全局的操作,比如创建视图,填充activity需要的数据等。 这个方法通过Bundle对象获取前一个Activity的数据。 NO onStart() onRestart() 在Activity停止后,再次被启动前调用。 Calledaftertheactivityhasbeenstopped,justpriortoitbeingstartedagain. NO onStart() onStart() 刚好在Activity将要被用户可见前调用,此时还不可以看到Activity所代表的界面。 NO onResume() 或 onStop() onResume() 当Activity所代表的页面可见的时候调用,在这个时候,该Activity位于Activity栈顶,拥有用户输入焦点。 NO onPause() onPause() 当系统启动另一个Activity时调用。 这个方法通常用于持久化未保存的数据的更改,停止动画,以及一些消耗CPU的操作。 尽管CPU的处理速度很快,但是它必须做上述操作,应为onPause方法没有返回的话是不能创建下一个Activity的(前提: 那些操作在主线程里—个人见解)。 YES onResume() 或 onStop() onStop() 当用户看不到该Activity所代表的界面时调用。 这个方法调用有两种情况: 1.当该Activity正在销毁。 2.另一个Activity启动或恢复并覆盖当前Activity。 YES onRestart() 或 onDestory() onDestory() Activity正在销毁时调用,这是一个Activity生命周期中接受的最后一个回调方法。 在正在调用Activity的finish方法前调用或者是系统内存不足导致不得不回收;想知道是哪一种销毁方式可以通过isFinishing()得知。 YES 以下对上图做一个简单的注释: Killableafter? 指出系统是否可以在任何上述方法执行完并返回后杀死持有当前Activity的进程。 onPause,onStop,onDestory三个方法被标注为YES,由于onPause方法是Activity创建后最有可能保证执行的方法,因此,当系统遇到紧急情况需要恢复内存,那么onStop,onDestory可能不被执行,因此你应当在onPause里保存一些至关重要的状态属性,当然你应当有选择性的做一些操作,不能太耗时,如果太耗时,那么其他的activity将不能被创建直到该activity的onPause方法执行完毕并返回。 注: 上表中标注为NO的方法执行后也可能杀死进程,不过这是一种非常极端的情况,要了解进程与线程,参考ProcessesandThreading文档。 2.保存Activity状态 管理Activity的生命周期这段简单的提到了当一个Activity处于暂停或停止状态,该activity的状态仍然保存。 当Activity执行onPause或onStop方法后,Activity对象仍然存在内存里,所以当你按手机上的back按钮时,会跳到上一个Activity,并且假如上一个Activity里面有一些EditText控件并填有值的话,那么返回之后还是会带值的。 然而,当系统为了回收内存而销毁一个Activity,当系统把该Activity销毁掉后,我们再导航到这个Activity时,系统不能就仅仅是简单的恢复该Activity,因为我们先前可能在Activity里填写了一些数据;相反的,我们要达到的一种效果是,当用户再返回到这个Activity时,就好像用户先前访问的一样,根本不会知道先前的Activity已经销毁而这个是重新构造的。 因此,在这种情况下,你可能需要一个可以保存你Activity状态的回调方法以确保你Activity的一些重要状态在销毁前被保存,当重新启动的时候再恢复这些状态,这个方法就是onSaveInstanceState(BundleoutState),outState所代替的Bundle对象就是你可以以键值形式保存Activity状态数据的地方,保存数据方法比如: putString()。 此时,若是系统杀死了你的Activity所在进程,而当用户重新访问这个Activity时候,系统将把你先前所保存状态的Bundle对象传给这个Activity的create()方法,因此,你可以恢复Activity先前所持有的状态;如果没有状态恢复,那么传递给create()方法的参数为null。 Note: 这里不能确保你的Activity对象销毁前一定调用onSaveInstanceState(BundleoutState)方法,比如,你按手机的BACK键,那么这是你确切的要销毁某个Activity对象,在这种情况下,onSaveInstanceState(BundleoutState)方法不会被调用,因为没有必要。 如果onSaveInstanceState(BundleoutState)方法被调用,那么它总是在onStop()被调用前调用,也许有可能在onPause()方法前被调用。 然而,即使你什么都不做或者不实现onSaveInstanceState(BundleoutState)方法,系统将可以以Activity的默认实现保存一部分你的Activity状态。 具体来说,默认的实现调用onSaveInstanceState(BundleoutState)方法时,会保存当前Activity布局中的每一个View控件的需要不存的基本状态。 几乎每一个view小部件都在onSaveInstanceState(BundleoutState)有适当的保存状态实现,因此当你ActiviyUI的任何改变都会被动态的保存并且当Activity重建时候恢复数据。 例如,EditText将保存用户输入的任何文本,CheckBox的选择状态。 当然,要达到自动保存的效果有一个必须条件,那就是必须为每个控件提供一个id(配置layout中的android: id),如果没有提供id,那么没有id的控件状态将不会被保存,例如没有id的EditText的文本不会保存,即重新创建Activity时不可恢复。 当然你也可以在layout布局文件里面加了id的控件再加一个android: saveEnabled=”false”属性,照样达到不可保存状态的目的。 当然,尽管默认的onSaveInstanceState(BundleoutState)实现能为你的Activity界面保存有有的状态,但是你同样需要重写该方法,为什么呢? 因为,假如你在做订单支付的账户,假如账户开始有10块钱,现在做了系列操作,用去了5块钱,……如果存在需要恢复的可能,你肯定不会再给账户页面显示10块钱吧,这样的话,你的生意没的做了。 上面陈述的情况是默认操作不能达到的。 由于默认实现非常有用,而用户重写onSaveInstanceState(BundleoutState)方法只是加一些额外的操作或变一些默认操作,所以在实现该方法的任何效果前,我们应该做到必须先调用 super.o
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- androidActivity 详解