尝试解析json文件时,函数无法返回结果

时间:2019-07-16 09:58:28

标签: android json

我有一个可以正常工作的android应用,其中列出了图书。通过为每本书创建一个Book对象,我的应用程序中的书被静态地逐一添加。我想更改我的应用程序接收书本的方式,以使我可以从json文件中读取所需的信息,而不是为每本书创建一个书本对象。我创建了一个解析json文件的函数,并以与初始化书本对象相同的方法调用了该函数。我想用parseJson函数替换通过新书对象添加每本书的代码块。这导致我遇到以下问题:

如果我删除了手动添加书本的代码块,并用parseJson函数替换了代码,则屏幕上不会出现书本。

如果我调用parseJson函数而不删除手动添加书籍的代码块,则该函数有效,并且每本书的副本都出现在屏幕上。

从本质上讲,问题可以归结为:如果删除了我初始化书本对象的代码块,则parseJson函数将不起作用。

这是我读取json文件的功能:

 private void parseJson() {
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
            (Request.Method.GET, "https://api.myjson.com/bins/15iviz", null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    Log.d("RESPONSE", response.toString());
                    try {
                        JSONArray array = response.getJSONArray("results");
                        JSONObject jsonObject = null;
                        for (int i = 0; i < array.length(); i++) {

                            jsonObject = array.getJSONObject(i);
                            String imageUrl = jsonObject.getString("url");
                            String title = jsonObject.getString("title");
                            String author = jsonObject.getString("author");
                            double price = jsonObject.getDouble("price");
                            int downloads = jsonObject.getInt("downloads");
                            int rating = jsonObject.getInt("rating");

                            Books.add( new Book(imageUrl, title, author, price, downloads, rating));

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

                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO: Handle error
                }
            });


    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsonObjectRequest);
} 

这是我声明书本实例的函数:

private void initImageBitmaps() {

    Log.i("HomeActivity", "initImageBitmaps()");


    Book book1 = new Book("https://imgur.com/5qLyBTr.jpg", "Doktor Ofboli", "Vasko Vasilev", 100.0, 321, 2);
    Book book2 = new Book("https://imgur.com/5qLyBTr.jpg", "Zoki Poki", "Vasko Vasilev", 70.0, 231, 3);
    Book book3 = new Book("https://imgur.com/5qLyBTr.jpg", "Sekerna Prikazna", "Vasko Vasilev", 30.0, 12, 1);
    Book book4 = new Book("https://imgur.com/5qLyBTr.jpg", "Pekolot", "Ivan Ivanov", 90.0, 666, 3);
    Book book5 = new Book("https://imgur.com/5qLyBTr.jpg", "Raj", "Ivan Ivanov", 0.0, 420, 4);
    Book book6 = new Book("https://imgur.com/5qLyBTr.jpg", "Kamasutra", "Ivan Ivanov", 0.0, 69, 5);
    Book book7 = new Book("https://imgur.com/5qLyBTr.jpg", "Cistsiliste", "Kiril Kirov", 50.0, 100, 3);

    Books.add(book1);
    Books.add(book2);
    Books.add(book3);
    Books.add(book4);
    Books.add(book5);
    Books.add(book6);
    Books.add(book7);

    parseJson();

    Log.e ("BOOKS", Books.toString());
   // parseExampleJson();

    initVereticalRecyclerView(Books);
    initFirstHorizontalRecyclerView(Books);
    initSecondHorizontalRecyclerView(Books);
}

如果删除了这些书籍实例,解析器将不会解析任何书籍,如果它们保留解析器将起作用,则每本书有两个实例,我该如何解决呢?

这是我正在解析的json:http://myjson.com/15iviz

请求的代码块:

private void initVereticalRecyclerView(ArrayList<Book> books) {

    Log.i("HomeActivity", "initRecyclerView()");

    RecyclerView recyclerView = findViewById(R.id.home_recycler_view3);
    HomeActivityViewAdapter adapter = new HomeActivityViewAdapter(this, books);
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
}

HomeActivity.java:这是所有已实现的代码的地方:https://codeshare.io/5PlwDw(当前从已声明的book对象和示例数组中获取图书)

如果需要,我将整个项目上传到github并在此处链接。

3 个答案:

答案 0 :(得分:0)

首先在gradle文件中添加依赖项implementation 'com.google.code.gson:gson:2.8.5'

像这样创建您的课程

    import java.util.List;

    public class BooksResponse {
    private ArrayList<Book> results;

    public void setResults(ArrayList<Book> results){
        this.results = results;
    }

    public ArrayList<Book> getResults(){
        return results;
    }

    @Override
    public String toString(){
        return 
            "Bookings{" + 
            "results = '" + results + '\'' + 
            "}";
        }
}

public class Book {
    private int downloads;
    private String author;
    private double price;
    private int rating;
    private String title;
    private String url;

    public void setDownloads(int downloads){
        this.downloads = downloads;
    }

    public int getDownloads(){
        return downloads;
    }

    public void setAuthor(String author){
        this.author = author;
    }

    public String getAuthor(){
        return author;
    }

    public void setPrice(double price){
        this.price = price;
    }

    public double getPrice(){
        return price;
    }

    public void setRating(int rating){
        this.rating = rating;
    }

    public int getRating(){
        return rating;
    }

    public void setTitle(String title){
        this.title = title;
    }

    public String getTitle(){
        return title;
    }

    public void setUrl(String url){
        this.url = url;
    }

    public String getUrl(){
        return url;
    }

    @Override
    public String toString(){
        return 
            "ResultsItem{" + 
            "downloads = '" + downloads + '\'' + 
            ",author = '" + author + '\'' + 
            ",price = '" + price + '\'' + 
            ",rating = '" + rating + '\'' + 
            ",title = '" + title + '\'' + 
            ",url = '" + url + '\'' + 
            "}";
        }
}

添加创建这样的方法

private ArrayList<Book> getBooks(String json){
        Gson gson=new Gson();
        BooksResponse books=gson.fromJson(json, BooksResponse.class);
        return books.getResults();
    }

现在将您的json响应传递给上述方法,并获取书籍列表

private void parseJson() {
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
            (Request.Method.GET, "https://api.myjson.com/bins/15iviz", null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    Log.d("RESPONSE", response.toString());
                    ArrayList<Book> books=getBooks(response.toString());
                    if(books!=null && books.size>0){
                     initVereticalRecyclerView(books);
                     initFirstHorizontalRecyclerView(books);
                     initSecondHorizontalRecyclerView(books);
                    }

                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO: Handle error
                }
            });


    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsonObjectRequest);
}

答案 1 :(得分:0)

您应该首先调用API,然后根据响应进行处理:

首先从调用initImageBitmaps()的位置调用parseJson()。 并在收到响应(无论是错误还是成功)之后,通过调用initImageBitmaps()处理它。

更新代码如下,从调用initImageBitmaps()的地方调用parseJson()。

    private void parseJson() {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, "https://api.myjson.com/bins/15iviz", null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d("RESPONSE", response.toString());
                        if(Books == null){
                            Books = new ArrayList<Book>();
                        }
                        try {
                            JSONArray array = response.getJSONArray("results");
                            JSONObject jsonObject = null;
                            for (int i = 0; i < array.length(); i++) {

                                jsonObject = array.getJSONObject(i);
                                String imageUrl = jsonObject.getString("url");
                                String title = jsonObject.getString("title");
                                String author = jsonObject.getString("author");
                                double price = jsonObject.getDouble("price");
                                int downloads = jsonObject.getInt("downloads");
                                int rating = jsonObject.getInt("rating");



                                Books.add( new Book(imageUrl, title, author, price, downloads, rating));
                            }


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

                        //HANDLE RESPONCE
                        initImageBitmaps();

                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO: Handle error

                        Toast.makeText(context, "No respose", Toast.LENGTH_SHORT).show();
                    }
                });


        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(jsonObjectRequest);
    }





    private void initImageBitmaps() {

        Log.i("HomeActivity", "initImageBitmaps()");

//
//        Book book1 = new Book("https://imgur.com/5qLyBTr.jpg", "Doktor Ofboli", "Vasko Vasilev", 100.0, 321, 2);
//        Book book2 = new Book("https://imgur.com/5qLyBTr.jpg", "Zoki Poki", "Vasko Vasilev", 70.0, 231, 3);
//        Book book3 = new Book("https://imgur.com/5qLyBTr.jpg", "Sekerna Prikazna", "Vasko Vasilev", 30.0, 12, 1);
//        Book book4 = new Book("https://imgur.com/5qLyBTr.jpg", "Pekolot", "Ivan Ivanov", 90.0, 666, 3);
//        Book book5 = new Book("https://imgur.com/5qLyBTr.jpg", "Raj", "Ivan Ivanov", 0.0, 420, 4);
//        Book book6 = new Book("https://imgur.com/5qLyBTr.jpg", "Kamasutra", "Ivan Ivanov", 0.0, 69, 5);
//        Book book7 = new Book("https://imgur.com/5qLyBTr.jpg", "Cistsiliste", "Kiril Kirov", 50.0, 100, 3);
//
//        Books.add(book1);
//        Books.add(book2);
//        Books.add(book3);
//        Books.add(book4);
//        Books.add(book5);
//        Books.add(book6);
//        Books.add(book7);
//
//        parseJson();

        Log.e ("BOOKS", Books.toString());
        // parseExampleJson();

        initVereticalRecyclerView(Books);
        initFirstHorizontalRecyclerView(Books);
        initSecondHorizontalRecyclerView(Books);
    }

原因:之所以发生这种情况是因为parseJson正在异步调用volley,并且在从parseJson获取数据后未处理其数据。您编写的静态代码之所以有效,是因为您在数组中添加书籍后调用了initImageBitmaps(),并且在获得Volley的响应后不会发生这种情况。

答案 2 :(得分:0)

通过调用在for循环后立即初始化recyclerviews的方法来解决。代码现在看起来像这样:

private void parseJson() {
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
        (Request.Method.GET, "https://api.myjson.com/bins/15iviz", null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d("RESPONSE", response.toString());
                try {
                    JSONArray array = response.getJSONArray("results");
                    JSONObject jsonObject = null;
                    for (int i = 0; i < array.length(); i++) {

                        jsonObject = array.getJSONObject(i);
                        String imageUrl = jsonObject.getString("url");
                        String title = jsonObject.getString("title");
                        String author = jsonObject.getString("author");
                        double price = jsonObject.getDouble("price");
                        int downloads = jsonObject.getInt("downloads");
                        int rating = jsonObject.getInt("rating");

                        Books.add( new Book(imageUrl, title, author, price, downloads, rating));

                    }

                    initVereticleRecyclerView(Books);
                    initFirstHorizontalRecyclerView(Books);
                    initSecondHorizontalRecyclerView(Books);

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

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
            }
        });

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsonObjectRequest);

}