SearchView 无意中启动可搜索 activity

SearchView launches searchable activity without intent

我正在使用 SearchView 启动一个显示搜索结果的新 activity。我关注了以下来源:

新的可搜索 activity ListActivityMainActivity 中应用栏内的 SearchView 小部件启动。新的可搜索 activity 已启动,但缺少搜索意图(从未调用 onNewIntent 方法)。

Searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint" >
</searchable>

AndroidManifest.xml

<application
    ...
    <meta-data
        android:name="android.app.default_searchable"
        android:value=".ui.ListActivity" />
    <activity
        android:name=".ui.MainActivity"
        ...
    </activity>
    <activity
        android:name=".ui.ListActivity"
        android:launchMode="singleTop"
        ...
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
    </activity>
</application>

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // setSupportActionBar
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);    
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false); 
        return true;
    }
}

ListActivity

public class ListActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {    
        Log.d(TAG, "onCreate invoked");    //Log Printed
        ...
    }

    @Override
    protected void onNewIntent(Intent intent) {
        Log.d(TAG, "onNewIntent invoked");    //Log NOT Printed
    }
}

考虑到我也用 new ComponentName(this, ListActivity.class) 替换了 getComponentName() 但得到了相同的结果:没有错误,没有意图查询。

根据onNewIntent()'s documentation

This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

singleTop 仅在 activity(在您的情况下为 ListActivity)位于顶部时才适用 - 它不会创建新实例,而是会重用现有实例。但是,如果您仅从 MainActivity 搜索(搜索后返回 ListActivity),那么您将销毁 ListActivity 实例,然后创建一个新实例 - 导致 onCreate() 被调用,但不是 onNewIntent().

onNewIntent 方法不会为 "first" Intent 和 activity 接收调用。查看文档 http://developer.android.com/intl/es/reference/android/app/Activity.html#onNewIntent(android.content.Intent).

在您的情况下,您只需在 onCreate 中调用 getIntent 即可获取您的搜索查询:

@Override
public void onCreate(Bundle savedInstanceState) {
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
    }
}