Activity 须知

来源:互联网 发布:知米和百词斩哪个好 编辑:程序博客网 时间:2024/05/17 21:45

Activity 须知

  1. 在 onCreate() 方法中创建 UI 元素,onResume() 中重新初始化在 onPause() 中释放掉的资源,在 onPause() 和 onStop() 中清除 Activity 的资源,在 onDestory() 中清除开启的线程。

  2. 当 Activity 长期处于 stop 状态,系统可能会因为内存不足回收该 Activity,但是此时系统会把 Activity 的状态通过 onSaveInstanceState() 保存到 Bundle 对象中,如果我们想要保存一些关键数据,可以在 onSaveInstanceState() 方法中添加相应键值保存,这个方法会在 onStop() 方法之前被调用,当然也可能是在 onPause() 之前。这种机制可以保证下次重建该 Activity 时,将 Bundle 传递到 onRestoreInstanceState() 方法和 onCreate() 中,这样我们就可以轻松地利用这些数据了,推荐在onRestoreInstanceState() 去恢复数据,因为 该方法中的 Bundle 一定是有值的,不用额外的判断是否为空,但是在 OnCreate() 中则需要进行判断。值得注意的是 onSaveInstanceState() 并不是每次 Activity 离开前台都会调用,系统只会在 Acitivty 被异常销毁并且有机会再次显示该 Activity 才会去调用它,什么是异常情况呢?比如系统因内存不足回收和资源相关的的系统配置发生变化等。

  3. Activity 的 singleTask 启动模式每次在启动 Activity 的时候会在整个 Activity 栈中查找,如果栈中存在该Activity 的实例,那么就会将 该实例置于栈顶,而那些位于该实例之上的 Activity 会被全部弹出栈,这也就意味着,如果一个存在着大量 Activity 的栈想要查找的实例位于栈的最底层,那么当该实例位于栈顶的时候栈中就只存在仅仅一个 Activity 实例了。

  4. 如果一个 启动模式为 singleTop 或者 singleInstance 的Activity 通过 startActivityForResult() 方法启动另一个 Activity,那么系统将会直接返回 ACTIVITY.RESULT_CANCELED 而不会去等待返回数据,系统在 Framework 层做了对这两种启动模式做了限制,以防两个不同的应用程序通过这种方法传递数据。

  5. 如果在 Service 中想要启动一个 Activity,通常需要 为 Intent 添加 Intent.FLAG_ACTIVITY_NEW_TASK, 因为 Service 中并不存在 Activity 栈,所以利用这条语句创建一个 Activity 栈。

  6. Activity 一般只关注与用于界面的相关操作,虽然可以再 Activity 使用 Asynctask 和 Handler 开启子线程执行耗时操作,但不推荐这么做,首选的做法是 将耗时任务委托给 Service,这样 Activity 就可以专注于用户界面。

  7. 如果想要控制一个 Activity 的启用和禁止,可以通过使用PackageManager API 操纵,首先将在 activity 的节点元素中添加以下属性

    android:enabled="flase"

    这个时候该 Activity 就已经是禁用的,这意味着 Activity 将不能再接受 Intent,下面就利用 PackageManager 将其设置为可用的

    PackageManager manager = getPackageManager();manager.setComponentEnabledSetting(        new ComponentName(this, MainActivity.class),        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,        PackageManager.DONT_KILL_APP);

如果想再次设置为禁用,操作是类似的,如下所示

 manager.setComponentEnabledSetting(                new ComponentName(this,MainActivity.class),                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,                PackageManager.DONT_KILL_APP        );

8.使用 ApplicationContext 去启动 standard 模式的 Activity 就会报错,因为 非 Activity 类型的 Context 根本就没有任务栈,这个时候只要为要启动的 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标志位就可以创建一个新的任务栈,这个时候 Activity 的启动模式为 singleTask。

9.可以通过两种方式为一个 Activity 设置启动模式。一种是在 AndroidManifest.xml中在节点中添加 launchMode ,这种方式无法为 Activity 设置 FLAG_ACTIVITY_CLEAR_TOP标识。另一种是为 Intent 添加标识位,但是这种方式无法为 Activity 指定 singleInstance 启动方式。

10.对于 singleTask 的启动模式,我们可以通过 taskAffinity 属性为其创建指定的任务栈,一般默认是包名。

11.通过 隐式方法启动 Activity 时,最好先判断一下当前系统中是否存在匹配的Activity ,然后再去启动,这样就可以避免因没有 Activity 匹配而出现的错误。可以通过PackageManager 中提供的 queryIntentActivities 来实现,如下示
首先,定义一个 Activity ,并且为其指定 intent 和 category 标签

    <activity android:name=".SecondActivity">        <intent-filter>            <action android:name="com.myapplication.intentone"></action>            <action android:name="com.myapplication.intenttwo"></action>            <category android:name="com.myapplication.category"></category>            <category android:name="android.intent.category.DEFAULT"></category>        </intent-filter>    </activity>

注意,android.intent.category.DEFAULT 是必须要有的,否则 该 activity 将无法使用隐式方式启动。

然后在 Activity 进行检测

        Intent intent = new Intent();        intent.setAction("com.myapplication.intentone");        intent.setAction("com.myapplication.intenttwo");        intent.addCategory("com.myapplication.category");        PackageManager manager = getPackageManager();        List<ResolveInfo> resolveInfos = manager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

事实上只要queryIntentActivities 的返回值不是 null,那么该 intent 必定可以启动成功。

0 0
原创粉丝点击