首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSONParser到ListView需要双倍

JSONParser到ListView需要双倍
EN

Stack Overflow用户
提问于 2016-07-17 03:40:12
回答 1查看 35关注 0票数 0

我有一个ListView,显示了从OMDBAPI搜索电影的标题,当点击搜索btn时,我需要点击两次而不是一次。

请帮帮忙。

代码如下:

代码语言:javascript
复制
public class JSONParser extends AsyncTask<String, String, String> {

    static ArrayList<String> movieList = new ArrayList<>();

    @Override
    protected String doInBackground(String... params) {

        HttpURLConnection httpURLConnection = null;
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();

        try {

            URL url = new URL(params[0]);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.connect();
            InputStream stream = httpURLConnection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            String line = "";
            while ((line = reader.readLine()) != null){
                builder.append(line);

            }
            return builder.toString();


        } catch (IOException e) {
            e.printStackTrace();
        }

        finally {
            if(httpURLConnection != null){
                httpURLConnection.disconnect();
            }
            try {
                if (reader != null){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return "Failed Connection";
    }



    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        try {
            JSONObject jsonObject = new JSONObject(result);
            JSONArray jsonArray = jsonObject.getJSONArray("Search");
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 1; i<jsonArray.length(); i++){
                JSONObject finalJsonObject = jsonArray.getJSONObject(i);
                String titleOfMovie = finalJsonObject.getString("Title");
                movieList.add(titleOfMovie);
                stringBuilder.append(movieList);
                finalJsonObject.get("Title");

            }


        } catch (JSONException e) {
            e.printStackTrace();
        }

    }
}

下面是mainActivivty:

代码语言:javascript
复制
public class Main2ActivityWeb extends AppCompatActivity {

    EditText searchBar;
    ListView listOfMovies;
    Button searchBtn;
    Button deleteBtn;
    ArrayAdapter<String> arrayAdapter;
    String url = "http://www.omdbapi.com/?s=";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2_activity_web);

        searchBar = (EditText) findViewById(R.id.etsearch);
        listOfMovies = (ListView) findViewById(R.id.lvMovies);
        searchBtn = (Button) findViewById(R.id.btnSearch);
        deleteBtn = (Button) findViewById(R.id.btnClear);

        searchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                arrayAdapter = null;
                final String search = url + searchBar.getText().toString();
                new JSONParser().execute(search);
                ArrayList<String> list = new ArrayList<>(JSONParser.movieList);
                arrayAdapter = new ArrayAdapter<>(Main2ActivityWeb.this,
                        android.R.layout.simple_list_item_1, list);
                listOfMovies.setAdapter(arrayAdapter);
                if (arrayAdapter !=null){
                    JSONParser.movieList.clear();
                }



            }
        });

        deleteBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listOfMovies.setAdapter(null);
                JSONParser.movieList.clear();
                searchBar.setText("");
            }
        });


    }
}
EN

回答 1

Stack Overflow用户

发布于 2016-07-17 04:00:37

您的问题是,您似乎不理解AsyncTask是异步的概念,所以

代码语言:javascript
复制
new JSONParser().execute(search);

onPostExecute完成之前,不会将任何内容存储到JSONParser.movieList中。

同时,您可以继续同步运行

代码语言:javascript
复制
ArrayList<String> list = new ArrayList<>(JSONParser.movieList);

当您第一次单击该按钮时,它很可能是空的,因为您仍在等待AsyncTask在后台完成对JSON的解析。

在第二次单击该按钮时,您将启动一个对JSON的新请求,但是您看到的结果来自第一个请求。

解决这个问题的一种方法是回调,就像Volley,Retrofit/OkHttp一样,但你也可以移动你使用的对象,以便它们以正确的顺序执行。例如,给AsyncTask提供ArrayAdapter,而不是让它维护自己的ArrayList

代码语言:javascript
复制
private ArrayList<String> list;

...

onCreate() {
    listOfMovies = (ListView) findViewById(R.id.lvMovies);
    list = new ArrayList<>();
    arrayAdapter = new ArrayAdapter<>(Main2ActivityWeb.this,
                        android.R.layout.simple_list_item_1, list);
    listOfMovies.setAdapter(arrayAdapter);

...
    onClick() {
        ...
        new JSONParser(arrayAdapter).execute(search);
    }
}

在AsyncTask中

代码语言:javascript
复制
public class JSONParser extends AsyncTask<String, String, String> {

    private ArrayAdapter<String> adapter;

    public JSONParser(ArrayAdapter<String> adapter) {
        this.adapter = adapter;
    }

    ...

    onPostExectute() {
        for (...) {
           adapter.add(titleOfMovie);
        }
        apdater.notifyDataSetChanged();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38414927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档