博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
fragment 出栈过程
阅读量:6691 次
发布时间:2019-06-25

本文共 4758 字,大约阅读时间需要 15 分钟。

hot3.png

当我们点击了返回键,首先收到消息的还是activity,如果回退栈有fragment,则有fragment manager处理, 否则调用finish():

//in class Activity/**     * Called when the activity has detected the user's press of the back     * key.  The default implementation simply finishes the current activity,     * but you can override this to do whatever you want.     */    public void onBackPressed() {        if (!mFragments.popBackStackImmediate()) {            finish();        }    }

在FragmentManager中(由FragmentManagerImp实现),首先将事务队列里尚未执行的事务执行完毕, 然后处理回退操作。实际使用的时候,时常可以看到这样的场景:点击一个按钮(会跳转到另一个fragment或activity)然后马上点击回退,可以感受到屏幕的闪烁, 在性能稍差的设备上尤其明显, 其实这些现象都可以在这里找到答案。

@Override    public boolean popBackStackImmediate() {        checkStateLoss();        executePendingTransactions();        return popBackStackState(mActivity.mHandler, null, -1, 0);    }

这里操作的是事务记录,虽然感觉像是操作的fragment。弹出事务时, 可以是弹出一个,也可以根据条件弹出多个(可以认为控制mBackStack的容量),然后对栈顶的事务执行恢复显示:即调用改事务的 popFromBackStack(boolean doStateMove)方法。

boolean popBackStackState(Handler handler, String name, int id, int flags) {        if (mBackStack == null) {            return false;        }        if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) {            int last = mBackStack.size()-1;            if (last < 0) {                return false;            }            final BackStackRecord bss = mBackStack.remove(last);            bss.popFromBackStack(true);            reportBackStackChanged();        } else {            int index = -1;            if (name != null || id >= 0) {                // If a name or ID is specified, look for that place in                // the stack.                index = mBackStack.size()-1;                while (index >= 0) {                    BackStackRecord bss = mBackStack.get(index);                    if (name != null && name.equals(bss.getName())) {                        break;                    }                    if (id >= 0 && id == bss.mIndex) {                        break;                    }                    index--;                }                if (index < 0) {                    return false;                }                if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) {                    index--;                    // Consume all following entries that match.                    while (index >= 0) {                        BackStackRecord bss = mBackStack.get(index);                        if ((name != null && name.equals(bss.getName()))                                || (id >= 0 && id == bss.mIndex)) {                            index--;                            continue;                        }                        break;                    }                }            }            if (index == mBackStack.size()-1) {                return false;            }            final ArrayList
 states                    = new ArrayList
();            for (int i=mBackStack.size()-1; i>index; i--) {                states.add(mBackStack.remove(i));            }            final int LAST = states.size()-1;            for (int i=0; i<=LAST; i++) {                if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));                states.get(i).popFromBackStack(i == LAST);            }            reportBackStackChanged();        }        return true;    }

最后是BackStackRecord的 popFromBackStack方法, 和BackStackRecord的 run() 方法是相对应的, 最后还是要通过FragmentManager的 moveToState来执行实际的处理(激活fragment的生命周期方法)

public void popFromBackStack(boolean doStateMove) {        if (FragmentManagerImpl.DEBUG) {            Log.v(TAG, "popFromBackStack: " + this);            LogWriter logw = new LogWriter(TAG);            PrintWriter pw = new PrintWriter(logw);            dump("  ", null, pw, null);        }        bumpBackStackNesting(-1);        Op op = mTail;        while (op != null) {            switch (op.cmd) {                case OP_ADD: {                    Fragment f = op.fragment;                    f.mNextAnim = op.popExitAnim;                    mManager.removeFragment(f,                            FragmentManagerImpl.reverseTransit(mTransition),                            mTransitionStyle);                } break;                case OP_REPLACE: {                    Fragment f = op.fragment;                    if (f != null) {                        f.mNextAnim = op.popExitAnim;                        mManager.removeFragment(f,                                FragmentManagerImpl.reverseTransit(mTransition),                                mTransitionStyle);                    }                    if (op.removed != null) {                        for (int i=0; i
= 0) {            mManager.freeBackStackIndex(mIndex);            mIndex = -1;        }    }

转载于:https://my.oschina.net/u/255456/blog/340770

你可能感兴趣的文章
Silverlight中 Content="{TemplateBinding Content}" bug
查看>>
Jsoup后台解析html、jsp网页
查看>>
中间件详解,Django复习
查看>>
微信小程序 md5加密
查看>>
python gui之tkinter事件处理
查看>>
Android Studio 1.1.0 切换主题和绑定 代码提示 快捷键
查看>>
读书笔记 UltraGrid(8)
查看>>
Spring Boot文档维护:集成Swagger2
查看>>
SharePoint 2010 部署架构
查看>>
BZOJ[3992][SDOI2015]序列统计 生成函数+NTT
查看>>
GUI自绘_其中左边树状菜单控件风格灵感来源于城市博物馆的壁灯效果。
查看>>
SSH 相关基础
查看>>
浅谈git和svn的区别
查看>>
JMETER 生成测试报告
查看>>
ScrollView中嵌套ListView
查看>>
XML再深入
查看>>
顺序表基础操作--练习
查看>>
Spring Cloud底层原理
查看>>
SSM前言——相关设计模式
查看>>
小清丽微距花卉拍摄示范
查看>>