创建Android搜索结果列表

创建Android搜索结果列表,android,android-activity,android-asynctask,listactivity,Android,Android Activity,Android Asynctask,Listactivity,我试图实现以下逻辑: 用户在文本框中输入搜索字符串(一个活动)->调用Web服务以异步执行搜索->搜索结果显示在列表中(另一个活动) 到目前为止,我有以下几点: 输入搜索字符串并单击“搜索”按钮的活动: public class Search extends Activity { // ... // called when "Search" button is clicked private void runSearch() { ProgressD

我试图实现以下逻辑:

用户在文本框中输入搜索字符串(一个活动)->调用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?
    }
    // ...
}
然后我有一个类来执行异步搜索:

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?
    }
    // ...
}
公共类SearchAsyncTask扩展了AsyncTask{
私有SearchAsyncTaskParam参数;
@凌驾
受保护的SearchAsyncTaskResult doInBackground(
SearchAsyncTaskParam…params){
如果(参数长度>0)
param=params[0];
SearchAsyncTaskResult=新建SearchAsyncTaskResult();
//调用Webservice并用状态(成功/失败)填充结果对象
//和点击列表(每个点击包含姓名、城市等)
返回结果;
}
@凌驾
受保护的void onPostExecute(SearchAsyncTaskResult){
param.ProgressDialog.disease();
如果(!result.Success)
//扔一个箱子
其他的
{
//这部分不完整,看起来不好,是吗?
//我如何将结果数据传递给新活动?
意向意向=新意向(param.ProgressDialog.getContext(),
SearchResultList.class);
param.ProgressDialog.getContext().startActivity(intent);
}
}
}
最后一个元素是显示搜索结果列表的活动:

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?
    }
    // ...
}
公共类SearchResultList扩展了ListActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setListAdapter(新阵列适配器(
这个,android.R.layout.simple_list_item_1,data));
//字符串仅用于测试,应该是包含数据的类
//对于每个项目,即名称、城市等,我从何处获取“数据”?
}
// ...
}
现在我的问题

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?
    }
    // ...
}
  • AsyncTask
    实例的
    onPostExecute
    方法中启动结果列表的活动是一个好主意吗?我已经用上面描述的简单测试对它进行了测试,它似乎很有效。但这是否安全,我是否在正确的线程(UI线程)上?如果这是一种不好的做法,那么启动结果活动的替代方案是什么

  • ProgressDialog
    的上下文用于
    Intent
    并启动活动看起来特别奇怪。它只是
    AsyncTask
    实例中唯一可用的上下文。这是否会是一个问题,因为
    ProgressDialog
    已被取消?我还可以使用什么上下文

  • 如何将结果数据传递到
    SearchResultList
    活动中

  • 如果搜索成功(上面的
    onPostExecute
    方法中的
    else
    案例),我想用文本框关闭
    search
    活动,这样,如果点击后退按钮,用户将返回主屏幕(搜索活动从中打开),而不是
    search
    活动。这可能吗?我该怎么做

  • 是的,因为您在UI线程上。如果您不使用AsyncTask,而只是使用一个简单的线程,则是另一种选择。在这种情况下,您将使用处理程序通知UI线程工作已完成。这是Asynctask存在的原因之一,因此您不必使用后一个版本

  • “使用ProgressDialog的上下文看起来特别奇怪 并开始活动。”

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

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

    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");
    
    如果您想传递自己的对象,请参见以下问题:

  • 可能吗?对在你的情况下,有两种方法可以做到这一点。或者,您可以像我一样,将SearchAsyncTask作为搜索类和just调用中的内部类编写

    Search.this.finish();
    
    如果某些条件成立,或者您可以查看此问题的公认答案:


  • 祝你好运

    谢谢,帮了大忙!(我已经把你的答案格式化了一点。)关于第三点,我不确定。无法将对象数组传递到
    putExtra
    ,只能传递基元类型?我理解对了吗?对于我来说,您链接的问题的答案看起来有点过头了,因为我实际上不想维护全局状态(在应用程序实例中),而只是将一些临时数据传递到活动中。没有别的办法吗?很高兴我能帮忙!只有基本类型(和字符串),是。还有一种方法可以做到这一点,但有点危险:您可以将数据对象声明为静态,并通过执行SearchAsyncTast.myObject直接从SearchResultList访问它。这是很危险的,因为您可能会导致内存泄漏。我只是在研究这个问题:对于
    putExtra
    ,似乎有一个重载,它需要一个
    Parcelable
    (另一个则需要一个
    Bundle
    )。如果我能利用这一点,我会仔细看看。乍一看,这似乎就是我要找的,不是吗?哦,酷,我不知道。是的,它会解决您的问题,但就过度杀伤力而言,第一个选项可能是较少的过度杀伤力=)