Android四大组件(一):Activity

2019-01-17  本文已影响7人  Rave_Tian

Activity是Android应用中负责与用户交互的组件,给Android应用提供可视化用户界面。Activity是Window的容器,Activity包含一个getWindow()方法,返回该Activity所包含的窗口。

创建Activity


Activity的生命周期

Activity的四个状态

Activity的四个状态

Activity生命周期及回调方法

Activity生命周期及相关的回调方法

Activity实践中的生命周期方法回调过程

Activity跳转时的生命周期方法回调过程

Activity跳转时生命周期

横竖屏切换的生命周期
默认情况下 ,横竖屏切换, 销毁当前的activity,重新创建一个新的activity。在一些特殊的应用程序常见下,比如游戏,不希望横竖屏切换activity被销毁重新创建。

//①通过清单文件配置Activity
android:screenOrientation="landscape"//始终横屏
android:screenOrientation="portrait"//始终竖屏

//②在代码中实现:
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//始终横屏
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //始终竖屏

2、通过清单文件配置Activity不再敏感横竖屏切换(相对更友好安全的做法,参见上文这也是兼容性更好的做法,如果需要在横竖屏切换时做业务逻辑处理,可以在onConfigurationChanged方法中实现):
在manifest.xml中配置activity:

android:configChanges="orientation|screenSize"

Activity的启动模式

所有的Activity都将存放在任务栈中,通过设置Activity的启动模式,可以修改任务栈的排列模式。我们可以在可以通过adb指令来查看系统的任务栈情况:adb shell dumpsys activity。 adb shell dumpsys activity activities | findstr "ResumedActivity"(这是用来查看当前活跃的栈顶Activity)。

Activity的四种启动模式

Standard启动模式 SingleTop模式Activity位于栈顶

②如果须要创建的Activity已经处于栈顶时,此时不会再创建新的Activity,而是直接复用栈顶的Activity,保证栈顶如果存在,不会重复创建。此时Activity的onCreate、onStart不会被系统调用,由于它并没有发生改变。但是它的的 onNewIntent会被回调。

SingleTop模式Activity不在栈顶 SingleTask模式复用

任务栈的相关理解
在上文的启动模式中我们多次提到任务栈这个概念,任务是一个activity的集合,它用栈(后进先出)的方式来管理activity;这个栈被称为返回栈(back stack),栈里的activity顺序是按打开顺序放置。

①当用户在home界面点击应用图标时候,这个应用的任务就会被转移到前台,如果这个应用的任务是空的,说明最近这个应用没有被启动过,系统就会去创建一个新的任务,将该应用的主activity放入到返回栈中。

②当一个activity启动了一个新activity的时候,新的activity会被放置到返回栈的栈顶并获取焦点(如果是SingleInstance启动模式,新的Activity会新建一个栈并独享);前一个activity仍然保留在任务栈,但处于停止状态。

③当用户按下返回键的时候,处于栈顶的activity会被移除掉,前一个activity就会重新回到栈顶的位置。我们只能向栈顶添加activity或者将栈顶的activity移除掉。

④如果一直按返回键,返回栈中的activity会一个一个的被移除,最终返回到主屏幕,这时候返回栈中activity全被清空,对应的任务也就不存在了。

通过SingleInstance启动模式理解任务栈

启动模式的使用方式
1、在Manifest.xml清单文件中静态指定启动模式:

        <activity
            android:name=".MainActivity"
            android:launchMode="singleTask"/>

2、在Intent中动态指定启动模式去创建Activity:

        Intent intent = new Intent();
        intent.setClass(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);

Activity异常结束时保存状态

Activity异常结束
Activity的异常结束是指,非人为主动结束和退出Activity的行为,一般有以下两种情况:
1、资源系统设置变更:如横竖屏切换,可能会导致Activity销毁重建,或者设备语音发生变化,或者键盘发生变化时。我们可以在清单文件中配置Activity的configChanges属性来避免(具体参照上文)。
2、系统资源不足时:由于虚拟机的垃圾回收机制,在系统内存不足时,会自动回收掉低优先级的进程,释放内存保证优先级高的进程能正常运行(Android进程优先级相关知识)。

在Activity异常结束时保存和恢复数据

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("name", "rave");
    }
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if(savedInstanceState != null){
            String name = savedInstanceState.getString("name");
            System.out.println(name);
        }
    }

Activity的之间的数据传递

当一个Activity启动另一个Activity时,或者当一个Activity关闭并返回时,常常会有一些数据需要传递。Android的做法是将数据以键值对的方式存放在Bundle中,让Intent携带Bundle在Activity之间完成数据传递。我们通过intent的putExtras()来添加数据,里面可以存放所以可序列化的类型(基本数据类型及其数组:byte、boolean、char、short、int、long、float、double、byte[]...;实现Parcelable接口的类;实现Serializable接口的类;还有这些类型的ArrayList集合类:ArrayList<? extends Parcelable>、ArrayList<Integer>、ArrayList<String>、ArrayList<CharSequence>)。???疑问这里Parcelable和Serializable有什么区别

Bundle bundle = new Bundle();
bundle.putBoolean("booleanValue", true);

Intent intent = new Intent();
intent.putExtras(bundle);

startActivity(intent);
//startActivityForResult(intent, 0);
Bundle bundle = getIntent().getExtras();
boolean value = bundle.getBoolean("booleanValue");
Bundle bundle = new Bundle();
bundle.putSerializable("booleanValue", true);

Intent intent = new Intent();
intent.putExtras(bundle);

setResult(1, intent);
finish();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Bundle bundle = data.getExtras();
}

Activity转场动画


使用Scheme方式唤起Activity

Android中启动Activity主要有两种方式,一种是通过显示意图启动,一种是通过隐式意图启动。这里介绍的使用Scheme方式唤起,其实是隐式意图启动的一种,因为这种方式在hybird开发中很常用所以提出来单独介绍。

android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面。客户端应用可以通过清单文件向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如商品详情页、活动详情页等等。也可以执行某些指定动作,如完成支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。

URL Scheme使用场景大致分以下几种

URL scheme协议格式
例如:xl://goods:8888/goodsDetail?goodsId=10011002

使用方式

1、必须在目标Activity的Manifest.xml中配置如下过滤器(关于Intent和Intent-filter会单独说明):

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="artist"
        android:host="first"
        android:path="/enter"/>
</intent-filter>

2、启动方式:

Intent intent = new Intent();
intent.setData(Uri.parse("artist://first/enter"));
startActivity(intent);

1、在目标Activity的Manifest.xml中配置如下过滤器

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data android:scheme="artist"
        android:host="first"
        android:path="/enter"/>
</intent-filter>

2、启动方式:

WebView.loadUrl("artist://first/enter");

相关源码分析

上一篇 下一篇

猜你喜欢

热点阅读