Android开发艺术探索 第一章

Android开发艺术探索  第一章

1.1生命周期

这个章节主要讲生命周期和源码调用分析,需要注意到的是,活动之间的跳转,在onPause不要进行重量级别操作。

  • Activity A 的onPause() → Activity B的onCreate() → onStart() → onResume() → Activity A的onStop();如果B是透明主题又或则是个DialogActivity,则不会回调A的onStop;

  • 使用onSaveInstanceState()保存简单,轻量级的UI状态

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    ...

    ActivityInfo aInfo = r.activityInfo;

    if (r.packageInfo == null) {

        //step 1: 创建LoadedApk对象

        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,

                Context.CONTEXT_INCLUDE_CODE);

    }

    ... //component初始化过程

    java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

    //step 2: 创建Activity对象

    Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

    ...

    //step 3: 创建Application对象

    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

    if (activity != null) {

        //step 4: 创建ContextImpl对象

        Context appContext = createBaseContextForActivity(r, activity);

        CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());

        Configuration config = new Configuration(mCompatConfiguration);

        //step5: 将Application/ContextImpl都attach到Activity对象

        activity.attach(appContext, this, getInstrumentation(), r.token,

                r.ident, app, r.intent, r.activityInfo, title, r.parent,

                r.embeddedID, r.lastNonConfigurationInstances, config,

                r.referrer, r.voiceInteractor);

        ...

        int theme = r.activityInfo.getThemeResource();

        if (theme != 0) {

            activity.setTheme(theme);

        }

        activity.mCalled = false;

        if (r.isPersistable()) {

            //step 6: 执行回调onCreate

            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

        } else {

            mInstrumentation.callActivityOnCreate(activity, r.state);

        }

        r.activity = activity;

        r.stopped = true;

        if (!r.activity.mFinished) {

            activity.performStart(); //执行回调onStart

            r.stopped = false;

        }

        if (!r.activity.mFinished) {

            //执行回调onRestoreInstanceState

            if (r.isPersistable()) {

                if (r.state != null || r.persistentState != null) {

                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,

                            r.persistentState);

                }

            } else if (r.state != null) {

                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);

            }

        }

        ...

        r.paused = true;

        mActivities.put(r.token, r);

    }

    return activity;

}

异常生命周期处理

资源改变导致活动重建,例如横竖屏切换,VIEW的状态会保存,具体可以看每个View的onSaveInstanceState保存了哪些状态。

横竖屏切换也可以设置android:configChanges="orientation"不改变,会回调onConfigurationChanged方法

资源不足也会导致优先级低的活动被杀死。前台活动优先级最高,最低是后台活动。

1.2启动模式

1. standard  标准模式,每次创建都会重新创建一个实例。用ApplicationContext启动会报错,因为任务栈是activity的类型,建议不存在任务栈时候,会用singleTask模式启动,创建新的任务栈,标记位FLAG_ACTIVITY_NEW_TASK。

2. singleTop  栈顶复用模式,处于任务栈顶会被复用,不会生成新的实例,而会调用onNewIntent方法,通过这个方法获取请求的信息。FLAG_ACTIVITY_SINGLE_TOP

3. singleTask 栈内复用模式,处于任务栈顶内被复用,不会生成新的实例,而会调用onNewIntent方法,通过这个方法获取请求的信息。如果任务栈不存在,会创建新的任务栈放入新的活动实例。等同于FLAG_ACTIVITY_NEW_TASK。

4.singleInstance 单实例模式,加强版singleTask,处于单独的任务栈中,后续请求均不会生成新的实例,除非独立的任务栈被系统销毁。

动态的Flags

1.FLAG_ACTIVITY_NEW_TASK  和singleTask一样

2.FLAG_ACTIVITY_SINGLE_TOP 和singleTop一样

3.FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK一起出现,和singleTask类似,栈内在它上面的活动都要出栈。

4.FLAG_ACTIVITY_EXCLUDE_REOM_RECENTS 不会出现在历史记录当中,和 android:excludefromrecents="true" 一样

活动都会放入任务栈当中,后进先出原则。

需要理解任务栈,TaskAffinity,这个参数标识一个活动需要的任务栈名称,一般默认是包名,也可以单独为活动指定TaskAffinity属性。

TaskAffinity主要和singleTask或者allowTaskReparenting使用,其他模式没有意义。

singleTask里面的任务栈指的就是TaskAffinity名称相同的任务栈。

allowTaskReparenting比较复杂,当A启动B,那边B启动后,会把A转移到B任务栈中。比如两个不同应用A和B,A启动B应用里面的一个C活动,那边C进入的B的任务栈,而不是A的,因为包名都不一样,这个时候启动B,会直接进入C活动,而不是B的主活动。

实现方式:

AndroidMenifest中定义

android:launchMode="standard"

代码中定义

Intent intent=new Intent();

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

1.3 IntentFilter匹配规则

显示调用和隐式调用。

action匹配规则:必须是字符串,匹配完全一样。如果存在多个,匹配一个就算成功。

cetegory匹配规则:必须是字符串,如果有,每个都需要匹配一样。默认是是android.intent.cetegory.DEFAULT.

data匹配规则:和action类似,结构比较复杂,分为mimeType(媒体类型)和URI。

scheme:URI模式,比如http、file、content

host:URI主机名

port:URI端口

Path、pathPattern、pathPrefix:都是代表路径,第一个是完整路径,第二个可以正则匹配,第三个表示路径前缀信息。

过滤规则:<data android:mimeType="image/*    /> 匹配所有类型的图片

<data android:mimeType="video/mpeg" android:scheme="http"...  

data android:mimeType="audio/mpeg" android:scheme="http"...  />  //符合其中一条即可

PackageManager的resolveActivity方法可以返回最佳符合活动,也可以用queryIntentActivites方法查询所有符合的活动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代我西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值