標籤:

activity的startActivity和context的startActivity有什麼不同嗎?


謝邀。

我們以 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 nbsp;
*`
* @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 中。


前者不用加newTask的flag,後者一般是Application,需要要加flag,否則會crash...再具體點就要看看裡面的代碼了。


activity的startActivity()方法可使用默認配置的launch flag,而context的startActivity()須包含FLAG_ACTIVITY_NEW_TASK的launch flag,原因是該context可能沒有現存的任務棧供新建的activity使用,必須顯式指定生成一個自己單獨的任務棧。

下面是API Reference:

activity.startActivity():

Launch a new activity. You will not receive any information about when the activity exits. This implementation overrides the base version, providing information about the activity performing the launch. Because of this additional information, the FLAG_ACTIVITY_NEW_TASK launch flag is not required; if not specified, the new activity will be added to the task of the caller.

This method throws ActivityNotFoundException if there was no Activity found to run the given Intent.

context.startActivity()

Launch a new activity. You will not receive any information about when the activity exits.
Note that if this method is being called from outside of an Activity Context, then the Intent must include the FLAG_ACTIVITY_NEW_TASK launch flag. This is because, without being started from an existing Activity, there is no existing task in which to place the new activity and thus it needs to be placed in its own separate task.
This method throws ActivityNotFoundException if there was no Activity found to run the given Intent.


推薦閱讀:

如何評價 Google 的新設計風格 Quantum Paper?
Android 開發者是如何解決不同解析度的兼容問題的?
Android activity與fragment之間通信的好的方法有哪些?
學習android開發需要哪些基礎?

TAG:Android開發 |