《Android开发艺术探索》读书笔记 (1) 第1章 Activity的生命周期和启动模式

前言

  • activity作为一个新\老android开发人员是熟悉不过了,不过细节决定成败,笔者把自己在实际开发中的遇到的问题总结下.鉴于之前已经记录了一片activity的日志,这边就只简单做知识点的归纳.

Activity生命周期

  1. 正常情况下:
    1.从APP中点击home键返回到系统桌面,在返回到activity,调用的是onRestart()这个方法.
    2.onStart()和onStop()对应,含义:是否可见,在后台;onResume()和onPause()对应,含义:是否恢复前台.且不能再onPause()中进行重量耗时操作.会影响到activity的显示
    3.Activity A到Activity B的过程总结,A.onPasue() - B.onCreate() - B.onStart() - B.onResume() - A.onStop();

  2. 异常情况下:
    1.资源相关的系统配置发生改变,例如:切换了系统语言,调用了输入键盘,旋转了手机屏幕;
    2.资源内存不足导致优先级低的activity被杀死
    以上两种情况会调用onSaveInstanceState()方法和onRestoreInstanceState(),前者在onStop()之前调用,后者在onStart()之后调用.
    可以通过在activity的menifest文件中配置activity的configChanges这个属性来避免其变化时候,activity发送重建.configChanges=”local\keyboardHidden\orientation”分别代表切换了系统语言,调用了输入键盘,旋转了手机屏幕;在activity中调用onConfigurationChanged()这个方法.

Activity启动模式

1.standard:这个没什么好说的,在activity栈中先进后出.
2.singleTop:笔者在做聊天APP的时候,用于聊天界面.配合onNewIntent()方法–主要用于通过notification通知新消息,点击唤醒chatactivity;onActivityResult()–配合startActivityForResult()返回聊天记录界面,更新聊天列表(因为接受了新消息,因此聊天列表用户顺序也会跟着发生改变)使用;
3.singleTask:笔者刚接触android的时候,很喜欢用这个方式去管理activity,感觉栈里面只有一个不用去想那么复杂,其实不然,而且所有activity启动模式都用它的话,管理起来很麻烦.并且如果是启动页面是singleTask的话,那么会出现BUG–用户按home键返回桌面的时候,每次重新进入APP,都回不到之前退出的数据,都是会重启整个APP
4.singleInstance:表示多个不同应用调用一个activity实例,例如:浏览器,笔者开发用得少,第三方调用的话,微信用的比较多,后面会说.
5.onNewIntent():主要是singleTop和singleTask这两种启动模式,如果在activity栈中都已存在实例,那么调用实例返回栈顶的时候,就会调用这个方法,不过,singleTask返回栈顶会移除再其之上的其他activity实例(栈的特性后进先出)
6.android:taskAffinity:在menifest的配置:通常和allowTaskReparenting或singleTask一起使用

    android:taskAffinity="com.max.test"  

其实,这个很少用到不过很有用,给大家简单举个例子就明白了:A代表一个APP,B代表微信,C代表B中分享朋友圈的activity并且c的menifest配置了taskAffinity并且allowTaskReparenting=true;那么B启动时候,C就在B的栈中了.

menifest的activity配置过滤规则

  • activity和service以及broadcast配置过滤规则都类似,只是简单说一下action,category和data三个过滤规则的区别:
    1.action:Intent中必须有一个action和menifest中的action中的任意一个匹配
    2.category:Intent中可以没有一个category,如果有那么和menifest中的category中的任意一个匹配
    3.data:跟action是类似的,不过Intent要调用setDataAndType的方法来指定属性和值.
 <data android:scheme="file" android:host="www.github.com"/>//menifest中配置代码
intent.setDataAndType(Uri.parse("file://abc"), "image/png");//java类中的代码

实际开发-activity栈管理问题

  • 根据笔者现目前开发的经验,有三种方式来管理activity栈,目前用的最多的是第三种:
    1.直接根据activity的在menifest中配置的4种启动模式,如果遇到需要跳转关闭的,直接在activity中获取要关闭的activity的instance实例,finish掉即可.这种方式缺点:不便于维护,代码混乱.直接上代码:
    2.全部都用singleTask模式来管理activity,如果需要置于栈底的activity重启,则重新初始化一个实例.这个方式比较奇葩,在公司项目中看见的,完全不推荐.开发中出现问题,和代码冗余的问题.
    3.通过一个单例模式的AppManager管理类,来对activity进行add,reomve等管理.但这种做法需要在写一个baseactivity基类,activity栈中每一个activity都需要去继承他.baseactivity主要的作用就是作为父类在每一个生命周期中,进行AppManger对activity栈的add和remove操作.
//管理方法1
public static Activity instance;//属性
instance = this;//把自身实例初始化
Activity.instance.finish();//在其他页面直接调用这个代码关闭activity
/**
 * 管理方法3
 * 应用程序Activity管理类:用于Activity管理和应用程序退出
 * @author Max
 * @created 2015-9-21
 */
public class AppManager {

    private static Stack activityStack;
    private static AppManager instance;

    private AppManager(){}
    /**
     * 单一实例
     */
    public static AppManager getAppManager(){
        if(instance==null){
            instance=new AppManager();
        }
        return instance;
    }
    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity){
        if(activityStack==null){
            activityStack=new Stack();
        }
        activityStack.add(activity);
    }
    /**
     * 获取当前Activity(堆栈中最后一个压入的)
     */
    public Activity currentActivity(){
        Activity activity=activityStack.lastElement();
        return activity;
    }
    /**
     * 结束当前Activity(堆栈中最后一个压入的)
     */
    public void finishActivity(){
        Activity activity=activityStack.lastElement();
        finishActivity(activity);
    }
    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity){
        if(activity!=null){
            activityStack.remove(activity);
            activity.finish();
            activity=null;
        }
    }
    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class cls){
        for (Activity activity : activityStack) {
            if(activity.getClass().equals(cls) ){
                finishActivity(activity);
            }
        }
    }
    /**
     * 结束指定类名的Activity
     */
    public boolean existsActivity(Class cls){
        for (Activity activity : activityStack) {
            if(activity.getClass().equals(cls) ){
                return true;
            }
        }
        return false;
    }
    /**
     * 结束所有Activity
     */
    public void finishAllActivity(){
        for (int i = 0, size = activityStack.size(); i < size; i++){
            if (null != activityStack.get(i)){
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }
    public void finishNotSpecifiedActivity(Class cls){
        for (int i = 0, size = activityStack.size(); i < size; i++){
            if (null != activityStack.get(i)&& activityStack.get(i).getClass()!=cls){
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }

    public int activietyCounts(){
        if (null!=activityStack){
            return activityStack.size();
        }
        return 0;
    }
    /**
     * 退出应用程序
     */
    @SuppressWarnings("deprecation")
    public void AppExit(Context context) {
        try {
            finishAllActivity();
            ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.restartPackage(context.getPackageName());
            System.exit(0);
        } catch (Exception e) { }
    }
}

项目源码

最后这个activity管理的使用方式,我会上传一个demo,http://download.csdn.net/detail/qq_28690547/9422803有兴趣的同学可以下载.如果对activity栈有更好的管理方式,欢迎留言交流

你可能感兴趣的:(读书笔记-android基础)