【问题标题】:Attempt to read from a null array using Volley and GSON尝试使用 Volley 和 GSON 从空数组中读取
【发布时间】:2015-11-26 22:01:22
【问题描述】:

我正在尝试制作的音乐播放器中使用 Volley。

这是我在音乐播放器中定义歌曲的方式。我有这个带有一些属性的“歌曲对象”

SongObject {

    public String albumArtURI;

    // Some other attributes 
}

为了获得albumArtURI,我对其进行了查询。如果 URI 不存在,我会尝试从 Internet 上下载一个图像 URL,但我收到此错误:

尝试从空数组中读取

所以这里是从互联网获取图像 url 并将其分配给歌曲对象的代码

 if(songObject.albumArtURI != null){

                    // The URI exists, so we leave as is

                } else {

                    // The album art URI does not exist,
                    // so we try to pull an album art .jpg URL down from iTunes
                    ServiceHandler serviceHandler = new ServiceHandler(MainActivity.this);
                    serviceHandler.getJSON_URL();               

                    songObject.albumArtURI = serviceHandler.JSONObjectsList[0].artworkUrl30; 
                    // Throws error "Attempt to read from a null array"
                }

所以从上面的代码可以看出,这一行抛出了错误

songObject.albumArtURI = serviceHandler.JSONObjectsList[0].artworkUrl30; 
// Gives error "Attempt to read from a null array"

但是,serviceHandler.JSONObjectsList[0].artworkUrl30 不应为空数组。

从后续类中的行可以看出,通过使用打印语句,所述变量不为空

Log.v("TAG",String.valueOf(JSONObjectsList[0].artworkUrl30)); 
// Prints http://is4.mzstatic.com/image/thumb/Music6/v4/68/b5/27/68b5273f-7044-8dbb-4ad1-82473837a136/source/30x30bb.jpg    

这是类本身:

public class ServiceHandler {

    Context ctx;
    SongInfo[] JSONObjectsList;
    String albumArtURI;
    String url = "https://itunes.apple.com/search?term=michael+jackson";

    public ServiceHandler(Context ctx){

        this.ctx = ctx;
    }

    public void getJSON_URL(){

        RequestQueue requestQueue = Volley.newRequestQueue(ctx);

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {

                // If there is a response, do this
                if (response != null) {

                    // Get the number of JSON objects on the web-page
                    int resultCount = response.optInt("resultCount");

                    // If there is a JSON object on the web-page, do this
                    if (resultCount > 0) {

                        // Get a gson object
                        Gson gson = new Gson();

                        // Get a JSONArray from the results
                        JSONArray jsonArray = response.optJSONArray("results");

                        // If the array exists, do this
                        if (jsonArray != null) {

                            // Convert the JSONArray into a Java object array 
                            JSONObjectsList = gson.fromJson(jsonArray.toString(), SongInfo[].class);

                            // Prints http://is4.mzstatic.com/image/thumb/Music6/v4/68/b5/27/68b5273f-7044-8dbb-4ad1-82473837a136/source/30x30bb.jpg
                            Log.v("TAG",String.valueOf(JSONObjectsList[0].artworkUrl30));                                                          
                        }
                    }
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("LOG", error.toString());
            }
        });

        requestQueue.add(jsonObjectRequest);
    }

    public class SongInfo {

        // Some attributes

        public String artworkUrl30;

        // Some more attributes
    }
}

所以我认为这个问题与 Volley 的异步特性有关?

试图在“填充”之前读取一个数组?

当 Volley 完成它的工作后,数组最终会被填充吗?

【问题讨论】:

    标签: android gson android-volley


    【解决方案1】:

    您的假设是正确的,这是因为异步。当 Volley 完成其任务(即调用并执行 onResponse 方法)时,它们的数组将包含数据。您可以使用接口从中获取数据。

    定义接口

    public interface MyInterface {
        public void myTask (SongInfo[] songInfo)
    }
    

    然后在你的 getJSON_URL 方法中使用接口作为参数

    getJSON_URL (MyInterface myInterface) {
    ...
    @Override
    public void onResponse(JSONObject response) {
    .....
    myInterface.myTask(JSONObjectsList);
    }
    

    然后在你的主课中

    ...
    serviceHandler.getJSON_URL(new MyInterface);
    @Override 
    public void myTask (SongInfo[] songInfo) {
    ...
    songObject.albumArtURI = serviceHandler.JSONObjectsList[0].artworkUrl30;
    ...
    }
    ...
    

    【讨论】:

    • 谢谢。有趣的是,当我在服务处理程序类中执行此albumArtURI = JSONObjectsList[0].artworkUrl30;,然后在主类中执行songObject.albumArtURI = serviceHandler.albumArtURI; 时,我没有收到“空数组错误”。这种策略是否可以让我避免使用界面来完成工作?界面似乎只是为了避免编译错误。这真的是界面所做的所有事情吗?只是帮助我避免编译错误?
    • 没有。当 volley 完成它的任务时(即执行响应),您调用接口的方法。而且我认为您遇到了运行时错误而不是编译错误?
    猜你喜欢
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多