您的位置:首页 > 移动开发 > Android开发

Android学习之Activity生命周期

2015-10-16 21:24 176 查看
活动

Android 中,Activity是所有程序的根本,所有程序的流程都运行在Activity 之中,Activity可以算是开发者遇到的最频繁,也是Android 当中最基本的模块之一。在Android的程序当中,Activity 一般代表手机屏幕的一屏。如果把手机比作一个浏览器,那么Activity就相当于一个网页。在Activity 当中可以添加一些Button、Check box 等控件。可以看到Activity 概念和网页的概念相当类似。

一般一个Android 应用是由多个Activity 组成的。这多个Activity 之间

可以进行相互跳转,例如,按下一个Button按 钮后,可能会跳转到其他的Activity。和网页跳转稍微有些不一样的是,Activity 之间的跳转有可能返回值,例如,从Activity A 跳转到Activity B,那么当Activity B 运行结束的时候,有可能会给Activity A 一个返回值。这样做在很多时候是相当方便的。

当打开一个新的屏幕时,之前一个屏幕会被置为暂停状态,并且压入历史堆栈中。用户可以通过回退操作返回到以前打开过的屏幕。可以选择性的移除一些没有必要保留的屏幕,因为Android会把每个应用的开始到当前的每个屏幕保存在堆栈中。

服务

Service 是android 系统中的一种组件,它跟Activity 的级别差不多,但是他不能自己运行,只能后台运行,并且可以和其他组件进行交互。Service 是没有界面的长生命周期的代码。Service是 一种程序,它可以运行很长时间,但是它却没有用户界面。这么说有点枯燥,来看个例子。打开一个音乐播放器的程序,这个时候若想上网了,那么,打开 Android浏览器,这个时候虽然已经进入了浏览器这个程序,但是,歌曲播放并没有停止,而是在后台继续一首接着一首的播放。其实这个播放就是由播放音 乐的Service进行控制。当然这个播放音乐的Service也可以停止,例如,当播放列表里边的歌曲都结束,或者用户按下了停止音乐播放的快捷键等。 Service 可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD 卡上文件的变化,再或者在后台记录地理信息位置的改变等等,总之服务嘛,总是藏在后头的。

开启Service有两种方式:

(1) Context.startService():Service会经历onCreate ->onStart(如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行, 则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次 );StopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用StopService的话,Service会一直在后台 运行。该Service的调用者再启动起来后可以通过stopService关闭Service。 注意,多次调用Context.startservice()不会嵌套(即使会有相应的onStart()方法被调用),所以无论同一个服务被启动了多少 次,一旦调用Context.stopService()或者StopSelf(),他都会被停止。补充说明:传递给StartService(0的 Intent对象会传递给onStart()方法。调用顺序为:onCreate -->onStart(可多次调用) -->onDestroy。

(2) Context.bindService():Service会经历onCreate() -->onBind(),onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind -->onDestroyed相应退出,所谓绑定在一起就共存亡了。

广播接收器

在Android 中,Broadcast是 一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver 是对发送出来的Broadcast进行过滤接受并响应的一类组件。可以使用BroadcastReceiver 来让应用对一个外部的事件做出响应。这是非常有意思的,例如,当电话呼入这个外部事件到来的时候,可以利用BroadcastReceiver 进行处理。例如,当下载一个程序成功完成的时候,仍然可以利用BroadcastReceiver 进行处理。BroadcastReceiver不能生成UI,也就是说对于用户来说不是透明的,用户是看不到的。BroadcastReceiver通过 NotificationManager 来通知用户这些事情发生了。BroadcastReceiver 既可以在AndroidManifest.xml 中注册,也可以在运行时的代码中使用Context.registerReceiver()进行注册。只要是注册了,当事件来临的时候,即使程序没有启 动,系统也在需要的时候启动程序。各种应用还可以通过使用Context.sendBroadcast () 将它们自己的Intent Broadcasts广播给其他应用程序。

内容提供

Content Provider 是Android提供的第三方应用数据的访问方案。

在Android[8]中, 对数据的保护是很严密的,除了放在SD卡中的数据,一个应用所持有的数据库、文件等内容,都是不允许其他直接访问的。Andorid当然不会真的把每个应 用都做成一座孤岛,它为所有应用都准备了一扇窗,这就是Content Provider。应用想对外提供的数据,可以通过派生Content Provider类, 封装成一枚Content Provider,每个Content Provider都用一个uri作为独立的标识,形如:content://com.xxxxx。所有东西看着像REST的样子,但实际上,它比REST 更为灵活。和REST类似,uri也可以有两种类型,一种是带id的,另一种是列表的,但实现者不需要按照这个模式来做,给id的uri也可以返回列表类型的数据,只要调用者明白,就无妨,不用苛求所谓的REST。

Activity生命周期:onCreate、onStart、onReStart、onResume、onPause、onStop、onDestory

和生命周期相关的行为:

1. 锁屏

2. 显示新页面,当前页面不在前台

3. 按返回键

4. 屏幕方向切屏

5. 在后台的页面被系统杀死了

publicclass Life1Activity extends Activity {

privateintparam=1;

//Activity创建时被调用

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

System.out.println("onCreate");

}

//Activity创建或者从后台重新回到前台时被调用

@Override

protectedvoidonStart() {

// TODO Auto-generated method stub

super.onStart();

System.out.println("onStart");

}

//Activity创建、从被覆盖再回到前台或者从后台重新回到前台时被调用

@Override

protectedvoidonResume() {

// TODO Auto-generated method stub

super.onResume();

System.out.println("onResume");

}

//Activity从后台重新回到前台时被调用

@Override

protectedvoidonRestart() {

// TODO Auto-generated method stub

super.onRestart();

System.out.println("onRestart");

}

//Activity被覆盖到下面或者锁屏时被调用

@Override

protectedvoidonPause() {

// TODO Auto-generated method stub

super.onPause();

System.out.println("onPause");

}

//退出当前Activity或者跳转到新Activity时被调用

@Override

protectedvoidonStop() {

// TODO Auto-generated method stub

super.onStop();

System.out.println("onStop");

}

//退出当前Activity时被调用,调用之后Activity就结束了

@Override

protectedvoidonDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

System.out.println("onDestroy");

}

/*

Activity被系统杀死时被调用.

例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.

另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.

在onPause之前被调用.

*/

@Override

protectedvoidonSaveInstanceState(Bundle outState) {

// TODO Auto-generated method stub

super.onSaveInstanceState(outState);

outState.putInt("param", param);

System.out.println("onSaveInstanceState");

}

/*

Activity被系统杀死后再重建时被调用.

例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.

这两种情况下onRestoreInstanceState都会被调用,在onStart之后.

*/

@Override

protectedvoidonRestoreInstanceState(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onRestoreInstanceState(savedInstanceState);

System.out.println("onRestoreInstanceState:"+savedInstanceState.getInt("param"));

}

//当指定了android:configChanges="orientation"后,方向改变onConfigurationChanged被调用

//模拟器转换屏幕:小键盘7

//api3.2以上版本:android:configChanges="orientation|screenSize"

//api3.2以下版本:android:configChanges="orientation|keyboardHidden"

//切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

@Override

publicvoidonConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

switch (newConfig.orientation) {

caseConfiguration.ORIENTATION_PORTRAIT:

setContentView(R.layout.activity_main2);

break;

caseConfiguration.ORIENTATION_LANDSCAPE:

setContentView(R.layout.activity_main);

break;

}

}

}

Activity与Task的关系

例如:Activity1---打开----Activity2----返回----Activity1:Activity与Task的关系

一个Activity可以启动另一个Activity,即使这个Activity是定义在另一个应用程序里的,比如说,你想展示给用户一条街的地图,现在已经有一个Activity可以做这件事,那么现在你的Activity需要做的就是将请求信息放进一个Intent对象里,并且将这个Intent对象传递给startActivity(),地图就可以显示出来了,但用户按下BACK键之后,你的Activity又重新出现在屏幕上。

对用户来说,显示地图的Activity和你的Activity好像在一个应用程序中的,虽然是他们是定义在其他的应用程序中并且运行在那个应用进程中。android将你的Activity和借用的那个Activity放进一个task里,以维持用户体验。简单来讲,task就是用户觉得好像是一个"应用程序"的东西。task是以栈的形式组织起来的一组相互关联的Activity,栈中底部的Activity就是开辟这个task的,通常是用户在应用程序启动器中选择的Activity。栈顶部的Activity是当前正在运行的Activity——用户正在交互操作的Activity。当一个Activity启动另一个Activity时,新启动的Activity被压进栈中,成为正在运行的Activity。旧的Activity仍然在栈中。当用户按下BACK键后,正在运行的Activity弹出栈,旧的Activity恢复成为运行的Activity。

改变启动的activity和第一个activity不在同一个task中:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

manifest文件中设置第二个activity的属性:android:taskAffinity="aaa.aaa"android:allowTaskReparenting="true"

taskAffinity用于指定当前Activity(activity1)所关联的Task,allowTaskReparenting用于配置是否允许该activity可以更换从属task,通常情况二者连在一起使用,用于实现把一个应用程序的Activity移到另一个应用程序的Task中

例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

示例:

我们首先写一个应用,它有两个Activity(Activity1和Activity2),AndroidManifest.xml如下:

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".Activity1"

android:taskAffinity="com.winuxxan.task"

android:label="@string/app_name">

</activity>

<activity android:name=".Activity2">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

Activity2的代码如下:

public class Activity2 extends Activity {

private static final String TAG = "Activity2";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main2);

}

@Override

public booleanonTouchEvent(MotionEvent event) {

Intent intent = new Intent(this, Activity1.class);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

return super.onTouchEvent(event);

}

}

然后,我们再写一个应用MyActivity,它包含一个Activity(MyActivity),AndroidManifest.xml如下:

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".MyActivity"

android:taskAffinity="com.winuxxan.task"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

我们首先启动MyActivity,然后按Home键,返回到桌面,然后打开Activity2,点击Activity2,进入Activity1。然后按返回键。

我们发现,我们进入Activity的顺序为Activity2->Activity1,而返回时顺序为Activity1->MyActivity。这就说明了一个问题,Activity1在启动时,重新宿主到了MyActivity所在的Task中去了。

10. 资源创建与使用

Android应用程序资源:

res文件夹下的资源:

res/anim/xxx.xml:定义动画的,xml使用:@anim/xxx java使用:R.anim.xxx

res/drawable/xxx.xml:定义静画

res/layout/xxx.xml:定义布局

res/values/arrays.xml:定义矩阵

res/values/colors.xml:定义颜色

res/values/dimens.xml:定义大小

res/values/string.xml:定义字符串

res/values/style.xml:定义样式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: