最近遇到HOME按键不能返回首页,纠结了好久,最终找到问题了,发现Launcher中主Activity没有加android.intent.category.DEFAULT属性,导致Intent匹配失败,通过隐式启动Activity时必须添加android.intent.category.DEFAULT属性,负责启动Activity会失败。
<activity
android:name="com.vlctech.launcher.MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:clearTaskOnLaunch="true"
android:windowSoftInputMode="stateUnchanged" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
按HOME键由PhoneWindowManager.java的launchHomeFromHotKey()方法开始最终会调用到frameworks\base\services\java\com\android\server\IntentResolver.java 的buildResolveList方法。
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
boolean debug, boolean defaultOnly,
String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
final String action = intent.getAction();
final Uri data = intent.getData();
final String packageName = intent.getPackage();
final boolean excludingStopped = intent.isExcludingStopped();
final int N = src != null ? src.length : 0;
boolean hasNonDefaults = false;
int i;
F filter;
for (i=0; i<N && (filter=src[i]) != null; i++) {
int match;
if (debug) Slog.v(TAG, "Matching against filter " + filter);
if (excludingStopped && isFilterStopped(filter, userId)) {
if (debug) {
Slog.v(TAG, " Filter's target is stopped; skipping");
}
continue;
}
// Is delivery being limited to filters owned by a particular package?
if (packageName != null && !packageName.equals(packageForFilter(filter))) {
if (debug) {
Slog.v(TAG, " Filter is not from package " + packageName + "; skipping");
}
continue;
}
// Do we already have this one?
if (!allowFilterResult(filter, dest)) {
if (debug) {
Slog.v(TAG, " Filter's target already added");
}
continue;
}
match = filter.match(action, resolvedType, scheme, data, categories, TAG);
if (match >= 0) {
if (debug) Slog.v(TAG, " Filter matched! match=0x" +
Integer.toHexString(match));
Log.i("jintuo"," new defaultOnly = " + defaultOnly);
if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
final R oneResult = newResult(filter, match, userId);
if (oneResult != null) {
dest.add(oneResult);
Log.i("jintuo","dest.add(oneResult)");
}
} else {
hasNonDefaults = true;
}
} else {
if (debug) {
String reason;
switch (match) {
case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
default: reason = "unknown reason"; break;
}
Slog.v(TAG, " Filter did not match: " + reason);
}
}
}
if (dest.size() == 0 && hasNonDefaults) {
Slog.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT");
}
}
按HOME键时打印 Slog.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT");
由此我们就找到 if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) 这里,发现找不到要启动的应用(HOME)的Intent.CATEGORY_DEFAULT及android.intent.category.DEFAULT属性,到此找到问题。