尝试使用 Volley 和 GSON 从空数组中读取
Attempt to read from a null array using Volley and GSON
我正在尝试制作的音乐播放器中使用 Volley。
以下是我在音乐播放器中定义歌曲的方式。我有这个 "song object" 和一些属性
SongObject {
public String albumArtURI;
// Some other attributes
}
为了得到albumArtURI
,我对其进行了查询。如果 URI 不存在,我尝试从互联网上下载图像 URL,但出现此错误:
Attempt to read from a null array
下面是从互联网获取图像 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
不应为空数组。
并且从后面class中的行可以看出,通过打印语句,上述变量不为空
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
这里是 class 本身:
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 的异步性质有关?
我正在尝试读取数组 "populated" 之前吗?
当 Volley 完成它的工作时,数组最终会被填充吗?
你的假设是正确的,这是因为异步。当 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);
}
然后在你的主要 class
...
serviceHandler.getJSON_URL(new MyInterface);
@Override
public void myTask (SongInfo[] songInfo) {
...
songObject.albumArtURI = serviceHandler.JSONObjectsList[0].artworkUrl30;
...
}
...
我正在尝试制作的音乐播放器中使用 Volley。
以下是我在音乐播放器中定义歌曲的方式。我有这个 "song object" 和一些属性
SongObject {
public String albumArtURI;
// Some other attributes
}
为了得到albumArtURI
,我对其进行了查询。如果 URI 不存在,我尝试从互联网上下载图像 URL,但出现此错误:
Attempt to read from a null array
下面是从互联网获取图像 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
不应为空数组。
并且从后面class中的行可以看出,通过打印语句,上述变量不为空
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
这里是 class 本身:
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 的异步性质有关?
我正在尝试读取数组 "populated" 之前吗?
当 Volley 完成它的工作时,数组最终会被填充吗?
你的假设是正确的,这是因为异步。当 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);
}
然后在你的主要 class
...
serviceHandler.getJSON_URL(new MyInterface);
@Override
public void myTask (SongInfo[] songInfo) {
...
songObject.albumArtURI = serviceHandler.JSONObjectsList[0].artworkUrl30;
...
}
...