activity的startActivity和context的startActivity区别
发布日期:2021-05-08 00:09:51 浏览次数:22 分类:精选文章

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

我们以 startActivity(Intent) 这个最常用的 api 来讲。

1. 首先,Context 类有一个 abstract 方法

/**     * Same as {@link #startActivity(Intent, Bundle)} with no options     * specified.     *     * @param intent The description of the activity to start.     *     * @throws ActivityNotFoundException       *`     * @see #startActivity(Intent, Bundle)     * @see PackageManager#resolveActivity     */    public abstract void startActivity(Intent intent);

2. Context 的一个子类叫 ContextWrapper ,ContextWrapper 虽然实现了 startActivity (Intent) 方法,但是很简单,因为需要实例化,所以必须要实现父类中的 abstract 方法。

@Override    public void startActivity(Intent intent) {        mBase.startActivity(intent);    }

3. ContextWrapper 有一个子类叫 ContextThemeWrapper ,这个类并没有实现startActivity(Intent) 方法。

4. Activity 的定义如下:

public class Activity extends ContextThemeWrapper        implements LayoutInflater.Factory2,        Window.Callback, KeyEvent.Callback,        OnCreateContextMenuListener, ComponentCallbacks2,        Window.OnWindowDismissedCallback {}
其实现了 startActivity(Intent) 方法:

/**     * Same as {@link #startActivity(Intent, Bundle)} with no options     * specified.     *     * @param intent The intent to start.     *     * @throws android.content.ActivityNotFoundException     *     * @see {@link #startActivity(Intent, Bundle)}     * @see #startActivityForResult     */    @Override    public void startActivity(Intent intent) {        this.startActivity(intent, null);    }    @Override    public void startActivity(Intent intent, @Nullable Bundle options) {        if (options != null) {            startActivityForResult(intent, -1, options);        } else {            // Note we want to go through this call for compatibility with            // applications that may have overridden the method.            startActivityForResult(intent, -1);        }    }

所以结论就是,这两个货是一样的...你在调用的时候,其实最终调用的都是 Activity 类实现的 startActivity 方法。

之所以会有这样的写法,是因为下面两个在 Activity 中是等价的

this.startActivity(intent);context.startActivity(intent);

另外 Context 的子类也有其他实现 startActivity 的,比如 ContextImpl.java, 这时候就需要一个 flag :FLAG_ACTIVITY_NEW_TASK ,否则就会抛出异常。

@Override    public void startActivity(Intent intent, Bundle options) {        warnIfCallingFromSystemProcess();        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {            throw new AndroidRuntimeException(                    "Calling startActivity() from outside of an Activity "                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."                    + " Is this really what you want?");        }        mMainThread.getInstrumentation().execStartActivity(                getOuterContext(), mMainThread.getApplicationThread(), null,                (Activity) null, intent, -1, options);    }

至于为什么非 Activity 实现的 startActivity 方法需要加这个 flag , 是因为在 Activity 的 startActivity 的实现中,会判断如果没有这个 flag , 就会自动把这个新的 Activity 加到现有的 task 里面。
而其他的 Context 或者其子类的实现中, 是没有这种判断的, 所以需要使用者指定这个 flag ,以便 AMS 将其加入到其自己的 task 中。

上一篇:Android开发内存优化方式? 避免 Out Of Memory(OOM)
下一篇:Android 代码技巧

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月11日 16时48分19秒