关于Activtity必须知道的

关于Activtity必须知道的


Acitivity的3种状态

  • 激活态:位于屏幕最前端

  • 暂停态:被一个透明或半透明Activity覆盖(Dialog

  • 停止态:被一个Activity完全覆盖

主要接口:

  • onCreate:创建时

  • onStart:在Framework中数据结构准备完毕后

  • onResume:来到栈的最前端,变为激活态时

  • onPause:从栈的最前端切换到后台,进入暂停态时

  • onStop:完全不可见时

  • onDestory:被清除时

Acitivity生命周期

 必调用的三个方法: onCreate()--> onStart() -->onResume() ,用AAA表示

  (1)父Activity启动子Activity,子Actvity退出,父Activity调用顺序如下
        AAA--> onPause() --> onStop() --> onRestart()-->onStart()--> onResume() …
  (2)用户点击HomeActvity调用顺序如下
        AAA--> onPause() --> onStop() --
Maybe-->onDestroy() – Maybe
  (3)调用finish()Activity调用顺序如下
        AAA--> onPause() --> onStop() -->onDestroy()
  (4)在Activity上显示dialogActivity调用顺序如下
        AAA
  (5)在父Activity上显示透明的或非全屏的activityActivity调用顺序如下
        AAA--> onPause()
  (6)设备进入睡眠状态,Activity
调用顺序如下
        AAA--> onPause()

onPauseonStop的区别

  • onPause用于由一个Activity转到另一个Activity、设备进入休眠状态(屏幕锁住了)、或者有dialog弹出时

  • onStop用于不可见的Activity(有对话框弹出时,这时底下的activity仍然可见,所以此时onStop不会被调用)

        从下面的日志日志可以看出区别:

        1.FirstActivity跳到SecondActivity

        FirstAcvity---> onCreate
        FirstAcvity--->onStart
        FirstAcvity--->onResume
        FirstAcvity--->onPause
        SecondActivity--->onCreate
        SecondActivity--->onStart
        SecondActivity--->onResume
        FirstAcvity--->onStop

        现在给AndroidMainfest.xml中的SeconedActivity属性加入android:theme="@android:style/Theme.Dialog",SeconedActivity将以对话框形式出现,不会对FirstAcvity形成遮盖.

        这时的状态输出为:

        FirstAcvity---> onCreate
        FirstAcvity--->onStart
        FirstAcvity--->onResume
        FirstAcvity--->onPause
        SecondActivity--->onCreate
        SecondActivity--->onStart
        SecondActivity--->onResume


        这时FirstAcvity比完全遮盖时少调用了onStop方法.


        以下两种情况下都只会触发onPause而不会触发onStop

        1.一个透明的包含DialogActivity出现

        2.poweroff锁屏

        显示一个非activityDialog,是不会调用onPauseonStop的,因为此Dialog属于activity

横竖屏切换时候Activity的生命周期:

  • 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次 (onPause -> onSaveInstanceState ->onStop ->onDestroy ->onCreate ->onStart ->onRestoreInstanceState ->onResume)

  • 设置Activity的android:configChanges=“orientation”时,横屏一样,竖屏时只会执行一次并执行onConfigurationChanged方法

  • 设置Activity的android:configChanges=“orientation|keyboardHidden”时,横屏、竖屏只会执行onConfigurationChanged方法

Activity管理:


        ActivityThread中mActivities保存所有ActivityClientRecord

        ActivityClientRecord中:

        IBinder token:Activity对象唯一标识


        Intent:用于完成各组件之间的消息传递

        Intent分为两类:

  • explicit Intent:指定了成员变量ComponentName mComponent

  • implicit Intent:需要查找Intent Filter来筛选组件

                Ø  action

                Ø  type

                Ø  categoty

        Task:Activity的集合

        ActivityStack管理Task:

        ArrayList<TaskRecord>mTaskHistory;

        TaskRecord表示Task,TaskRecord存储了Activity列表:

        ArrayList<ActivityRecord>mActivities;

如何开始一个新的Task:

        1.      Intent中定义FLAG_ACTIVITY_NEW_TASK

        2.      AndroidManifest.xml  -> <activity>标签  ->  修改taskAffinity属性

        taskAffinity缺省值是应用包名,如果不修改会将旧的Task带到前台

Acitivity对象的复用:


<activity>标签launchMode属性:

  • Standard :每次都会创建新的实例对象

  • singleTop :如果实例位于Task栈顶,切换到前台,调用onNewIntent()

  • singleTask :只存在一个实例对象

  • singleInstance :只存在一个实例对象,只位于特定的Task

Acitivity在不同Task之间转移

        1.      <activity>标签allowTaskReparenting属性设为true

        2.      启动的Intent设置FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标志

让Acitivity长时间处在后台不被系统销毁

        <activity>标签alwaysRetainTaskState属性设为true

让Acitivity启动时销毁已存在的实例,再重新启动一个新的

        <activity>标签finishOnTaskLaunch属性设为true

Activity启动过程

ActivityStackSupervisor.java:

final int startActivityMayWait(IApplicationThread caller, int callingUid, …) {
        …
intent = new Intent(intent);
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
                profilerInfo, userId);
…
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options,
                    componentSpecified, null, container, inTask);

if (outResult != null) {
                outResult.result = res;
                if (res == ActivityManager.START_SUCCESS) {
                    mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (!outResult.timeout && outResult.who == null);
                }
				…
            }
		…
}

        1.      resolveActivity()调用ActivityManagerService.resolveIntent()获取ActivityInfo

        2.      startActivityLocked继续启动Activity

        3.      如果Activity需要返回结果,调用mService.wait()挂起线程

startActivityLocked() :

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
            TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;
        ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);		//得到调用进程的信息
            …
        }
	…		//错误检查
        final int startAnyPerm = mService.checkPermission(
                START_ANY_ACTIVITY, callingPid, callingUid);		//检查调用者权限
        …
	//检查Intent防火墙(/data/system/ifw目录下的配置)是否屏蔽了该Intent
        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        if (mService.mController != null) {
            try {
                // The Intent we give to the watcher has the extra data
                // stripped off, since it can contain private information.
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }
        if (abort) {
            …
            return ActivityManager.START_SUCCESS;
        }
	//创建ActivityRecord对象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, this, container, options);
        if (outActivity != null) {
            outActivity[0] = r;
        }
	//取得当前接收用户输入的ActivityStack
        final ActivityStack stack = getFocusedStack();
        if (voiceSession == null && (stack.mResumedActivity == null
                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
	//如果需要进行进程切换,检查是否有权限
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
			//现在不能切换进程,吧Activity信息放入mPendingActivityLaunches列表
                PendingActivityLaunch pal =
                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
                mPendingActivityLaunches.add(pal);
                ActivityOptions.abort(options);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }
        if (mService.mDidAppSwitch) {
            // This is the second allowed switch since we stopped switches,
            // so now just generally allow switches.  Use case: user presses
            // home (switches disabled, switch to home, mDidAppSwitch now true);
            // user taps a home icon (coming from home so allowed, we hit here
            // and now allow anyone to switch again).
            mService.mAppSwitchesAllowedTime = 0;
        } else {
            mService.mDidAppSwitch = true;		//打开开关,允许进程间切换
        }
        doPendingActivityLaunchesLocked(false);		//启动挂起等待的Activity
	//继续启动当前的Activity
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
        if (err < 0) {
            // If someone asked to have the keyguard dismissed on the next
            // activity start, but we are not actually doing an activity
            // switch...  just dismiss the keyguard now, because we
            // probably want to see whatever is behind it.
            notifyActivityDrawnForKeyguard();		//打开锁屏界面
        }
        return err;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值