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

来源:互联网 发布:淘宝卖家流量钱包 编辑:程序博客网 时间:2024/05/16 11:28

前言

  • 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操作.
//管理方法1public static Activity instance;//属性instance = this;//把自身实例初始化Activity.instance.finish();//在其他页面直接调用这个代码关闭activity
/** * 管理方法3 * 应用程序Activity管理类:用于Activity管理和应用程序退出 * @author Max * @created 2015-9-21 */public class AppManager {    private static Stack<Activity> 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<Activity>();        }        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栈有更好的管理方式,欢迎留言交流

0 0