• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android插件开发-就是你了!启动吧!插件的activity(二)

android插件开发-就是你了!启动吧!插件的activity(二)

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android插件开发-就是你了!启动吧!插件的activity(二)等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android插件开发-就是你了!启动吧!插件的activity(二)


这篇博客是上篇的延续,在阅读之前先阅读第一部分:第一部分
我们在启动插件的activity时,通过替换component成功欺骗AMS获得了启动一个activity所必须的一些资源。不过,我们还没有把获取的那些资源都转移到插件的activity之下。这一节就是解决这个问题。

所有的答案都是分析源码之后得到的,所以我们还和之前一样继续分析源码,看下AMS是怎么把资源关联到一个activity上的,这样我们才有可能转移这些资源到插件的activity之下。

在上一篇博文中我们分析到了startActivityLocked函数。在这个函数里面,我们在获得启动一个activity的信息,和要启动的activity信息之后,我们转到了startActivityUncheckedLocked函数:

    final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
        ...

        //用来判断是否需要重新创建一个新的任务栈来启动这个activity
        //在我们这里例子里面 我们newTask会一直是false
        boolean newTask = false;
        boolean keepCurTransition = false;

        ...

        // Should this be considered a new task?
        if (r.resultTo == null && inTask == null && !addingToTask
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
           ...
        } else if (sourceRecord != null) {
        } else ....

        ....

        //调用ActivityStack的成员函数
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        ...
        return ActivityManager.START_SUCCESS;
    }

之后调用的是startActivityLocked方法:

 final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        ...
        if (!newTask) {
            // If starting in an existing task, find where that is...
            boolean startIt = true;
            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
                task = mTaskHistory.get(taskNdx);
                if (task.getTopActivity() == null) {
                    // All activities in task are finishing.
                    continue;
                }
                if (task == r.task) {
                    // Here it is!  Now, if this is not yet visible to the
                    // user, then just add it without starting; it will
                    // get started when the user navigates back to it.
                    if (!startIt) {
                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
                                + task, new RuntimeException("here").fillInStackTrace());
                        task.addActivityToTop(r);
                        r.putInHistory();
                        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
                                r.userId, r.info.configChanges, task.voiceSession != null,
                                r.mLaunchTaskBehind);
                        if (VALIDATE_TOKENS) {
                            validateAppTokensLocked();
                        }
                        ActivityOptions.abort(options);
                        return;
                    }
                    break;
                } else if (task.numFullscreen > 0) {
                    startIt = false;
                }
            }
        }
        ...

        //把要启动的activity压入活动栈中
        task.addActivityToTop(r);
        task.setFrontOfTask();

        ...

        //我们显然是要让activity显示 所以这里一定会执行
        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
    }

这个函数做的事情很简单,就是把要启动的activity压到活动栈的栈顶,这里又证实了我们之前的猜想:

AMS解析Intent,获得ActivityRecord,而ActivityRecord用来表示一个activity,至于如何解析Intent获得ActivityRecord,内容和网上一些intent解析过程一样intent解析过程 ,而我们在代码中是显示启动一个activity,所以我们替换ComponeneName就可以

接下来我们继续转到StackSupervisor中去查看resumeTopActivitiesLocked
这里写图片描述
看下是否是最前面的一个任务活动栈(很好理解,因为你不可能一次只开一个应用,你可能在使用手机时打开QQ,微信,微博,他们都各自对应很多个活动栈),是的话就准备响应他

stack.resumeTopActivityLocked:
这里写图片描述
最后都转发到了resumeTopActivityInnerLocked
查看下:

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        ...

        // We need to start pausing the current activity so the top one
        // can be resumed...
        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
            //调用start[
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }

        ...
        return true;
    }

在确认一切无误之后调用startPausingLocked方法

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
            boolean dontWait) {

        ...
        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            try {
                ...
                //prev.app.thread返回一个IApplicationThread
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } catch (Exception e) {
                ...
            }
        } else {
              ...
        }
        ...
    }

prev.app.thread返回一个IApplicationThread,它通知Ui线程可以终止当前正在响应的activity了,我要开启新的activity了!

  prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);

在本例中就是:
这里写图片描述

这里prev.appToken是一个IBinder对象,其他的都是Boolean还有Configuration类型,我们不难得出,AMS区分activity是谁就是通过这个IBinder对象(Token是IBinder的实现类)!!!

这里写图片描述

为了验证我们的猜想,还是继续阅读源码:
这里写图片描述

Handler中的处理代码:
这里写图片描述
IBinder被保存在Message的obj中,之后调用handlePauseActivity函数:
这里写图片描述

 //mActiv



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-26android中使用图文并茂的按钮,android图文并茂
  • 2017-05-26Android—ZXing二维码扫描遇到的问题,androidzxing
  • 2017-05-26linux syslog日志服务器的搭建
  • 2017-05-26android中常见的设计模式有哪些?,android设计模式
  • 2017-05-26Android安全专项之Xposed劫持用户名密码实践
  • 2017-05-26android:常用的AlertDialog对话框及自定义对话框
  • 2017-05-26NDK-JNI实战教程(二) JNI官方中文资料,ndk-jnijni
  • 2017-05-222.4.7ListView的焦点问题
  • 2017-05-26[转]File Descriptor泄漏导致Crash: Too many open files,descriptorcrash
  • 2017-05-26Webview内存泄漏解决办法1,webview泄漏

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 连点处理,禁止按钮在短时间内被多次点击,按钮短时间内
    • 当EditText编辑时 hint 在 6.0 手机上显示不出来,edittexthint
    • Java时间间隔问题在Android中的使用,javaandroid
    • Android微信支付SDK开发,android支付sdk
    • 2016年Android市场的8个大胆预测,2016年android
    • Android中TextView、EditText对部分内容设置不同格式(颜色、字体、超链接、图片。。)
    • 一个难倒 3年 android开发经验 " 工程师 " 的 "bug"
    • Android与H5互调(通过实例来了解Hybrid App),androidhybrid
    • 关于Android中的三级缓存,
    • 2.2.2 RelativeLayout(相对布局)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有