【问题标题】:SearchView launches searchable activity without intentSearchView 无意识地启动可搜索活动
【发布时间】:2016-05-22 15:03:05
【问题描述】:

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

新的可搜索活动ListActivity 是从MainActivity 应用栏中的 SearchView 小部件启动的。新的可搜索活动已启动,但缺少搜索意图(从未调用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;
    }
}

列表活动

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(),但得到了相同的结果:没有错误,没有意图查询。

【问题讨论】:

    标签: android android-intent searchview


    【解决方案1】:

    根据onNewIntent()'s documentation

    如果活动在其包中将 launchMode 设置为“singleTop”,或者客户端在调用 startActivity(Intent) 时使用了 FLAG_ACTIVITY_SINGLE_TOP 标志,则会调用此函数。在任何一种情况下,当活动在活动堆栈的顶部而不是正在启动的活动的新实例时重新启动时,onNewIntent() 将在具有用于重新启动的 Intent 的现有实例上调用它。

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

    【讨论】:

    • 谢谢,但是啊,我看到我忘了在此处添加启动模式,但它确实存在于我的代码中。让我更新这个问题。不幸的是,答案并不适用......
    • 您是否在您的ListActivity 中进行搜索?还是总是从MainActivity 搜索?显然,当您回击 ListActivity 时,该实例已被破坏,并且您在再次搜索时创建一个新实例 - 再次,不是现有 Activity 的新 Intent。
    • 也更新了我的答案
    • 现在我明白了。一切运行良好,但我根本没有使用getIntent().getStringExtra(SearchManager.QUERY) 读取onCreate 方法中的查询。不是一件困难的事情,但是android教程(我的问题中的第一个链接)甚至没有提到这个!
    • 我在Providing Search with SearchView video4 minutes in 中提出了它。仍在努力更新文档(或至少添加了指向视频的链接!)
    【解决方案2】:

    onNewIntent 方法不会为活动接收到的“第一个”Intent 调用。查看文档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);
        }
    }
    

    【讨论】:

    • 谢谢,这个答案很好,但选择的答案更能帮助我了解全貌!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    相关资源
    最近更新 更多