【问题标题】:Creating an Android search result list创建 Android 搜索结果列表
【发布时间】:2011-10-02 14:18:42
【问题描述】:

我正在尝试实现以下逻辑:

用户在文本框中输入搜索字符串(一个活动) -> 调用 Web 服务以异步执行搜索 -> 搜索结果显示在列表中(另一个活动)

到目前为止,我有以下内容:

一个输入搜索字符串并点击“搜索”按钮的活动

public class Search extends Activity
{
    // ...
    // called when "Search" button is clicked
    private void runSearch()
    {
        ProgressDialog progressDialog = ProgressDialog.show(
            this, "Search", "Search...");
        searchAsyncTask = new SearchAsyncTask();

        SearchAsyncTaskParam param = new SearchAsyncTaskParam();
        param.SearchString = getSearchCode(); // gets input from text box
        param.ProgressDialog = progressDialog;

        searchAsyncTask.execute(param);
    }
}

然后我有一个类来执行异步搜索

public class SearchAsyncTask extends AsyncTask<SearchAsyncTaskParam,
    Void, SearchAsyncTaskResult> {

    private SearchAsyncTaskParam param;

    @Override
    protected SearchAsyncTaskResult doInBackground(
        SearchAsyncTaskParam... params) {
        if (params.length > 0)
            param = params[0];
        SearchAsyncTaskResult result = new SearchAsyncTaskResult();

        // call Webservice and fill result object with status (success/failed)
        // and a list of hits (each hit contains name, city, etc.)

        return result;
    }

    @Override
    protected void onPostExecute(SearchAsyncTaskResult result) {
        param.ProgressDialog.dismiss();
        if (!result.Success)
            // throw an AlertBox
        else
        {
            // this part is incomplete and doesn't look good, does it?
            // And how would I pass my result data to the new activity?
            Intent intent = new Intent(param.ProgressDialog.getContext(),
                SearchResultList.class);
            param.ProgressDialog.getContext().startActivity(intent);
        }
    }
}

最后一个元素是显示搜索结果列表的活动

public class SearchResultList extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<String>(
            this, android.R.layout.simple_list_item_1, data));
        // String was only for testing, should be a class with holds the data
        // for each item, i.e. Name, City, etc. And where do I get "data" from?
    }
    // ...
}

现在我的问题

  1. AsyncTask 实例的onPostExecute 方法中为结果列表启动活动是否是个好主意?我已经用上面勾勒的简单测试对其进行了测试,它似乎有效。但这安全吗,我在正确的线程(UI线程)上吗?如果这是不好的做法,那么启动结果活动的替代方法是什么?

  2. ProgressDialog 的上下文用于Intent 并启动活动看起来特别奇怪。这只是我在 AsyncTask 实例中可用的唯一上下文。这可能是一个问题,因为ProgressDialog 已经被解雇了吗?我还可以使用什么上下文?

  3. 如何将结果数据传递到SearchResultList 活动?

  4. 1234563用户返回到主屏幕(从中打开搜索活动)而不是Search 活动。这可能吗?我该怎么做?

【问题讨论】:

    标签: android android-activity android-asynctask listactivity


    【解决方案1】:
    1. 是的,因为您在 UI 线程上。另一种选择是如果您不使用 AsyncTask 而只是一个简单的线程。在这种情况下,您将使用 Handler 来通知 UI 线程工作已完成。这是 Asynctask 存在的原因之一,因此您不必执行后一个版本。

    2. "使用 ProgressDialog 的上下文看起来特别奇怪 用于 Intent 并启动 Activity。”

      这一点都不奇怪,因为当您创建 ProgressDialog 时,您传递了 Search 的上下文,因此当您检索 ProgressDialog 的上下文时,您实际上获得了 Search 活动的上下文。完全没问题。

    3. 这取决于您要传递的数据。如果你只想传递一个字符串数组,你可以这样做:

      String [] data = getData();
      Intent intent = new Intent(param.ProgressDialog.getContext(),
          SearchResultList.class);
      intent.putExtra("key1", data);
      param.ProgressDialog.getContext().startActivity(intent);
      

      然后在 SearchResultList 活动中你会这样做:

      String [] data = this.getIntent().getStringArrayExtra("key1");
      

      如果您想传递自己的对象,请参阅此问题:How to declare global variables in Android?

    4. 有可能吗?是的。在您的情况下,有两种方法可以做到这一点。您可以像我一样将 SearchAsyncTask 编写为 Search 类中的内部类,然后直接调用

      Search.this.finish();
      

      如果某些条件成立,或者您可以查看此问题的已接受答案:android how to finish an activity from other activity

    祝你好运!

    【讨论】:

    • 谢谢,帮了大忙! (我已经对您的答案进行了一些格式化。)关于第 3 点我不确定。不可能将对象数组传递给putExtra,只有原始类型?我理解正确吗?就我的目的而言,您链接的问题的答案看起来有点矫枉过正,因为我实际上不想维护全局状态(在应用程序实例中),而只是将一些临时数据传递到活动中。没有别的办法吗?
    • 很高兴我能帮上忙!只有原始类型(和字符串),是的。还有另一种方法,但有点危险:您可以将数据对象声明为静态并通过执行 SearchAsyncTast.myObject 直接从 SearchResultList 访问它。这很危险,因为您可能会导致内存泄漏。
    • 我正在研究这个:stackoverflow.com/questions/2139134/… putExtra 似乎有一个过载,它需要一个Parcelable(另一个需要一个Bundle)。如果我能利用这一点,我会仔细看看。乍一看,这似乎就是我要找的东西,不是吗?
    • 哦,酷,我不知道。是的,它会解决你的问题,但就矫枉过正而言,第一个选择可能不那么矫枉过正=)
    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2014-12-22
    相关资源
    最近更新 更多