I'm trying to retrieve JSON data from an external source for practice. I have gotten all the code in place but for some reason I get an error saying that the document is not fully consumed. I have watched and read multiple tutorials and guides, but still can't seem to get it right. I have also searched stack for answers, but since I don't know what's wrong, I don't really know what to look for.
All the code is in place and there is no obvious fault in it. The JSON data has been validated and it works to retrieve as raw JSON data, as seen in a log. The problem occur at the Gson conversion when the data should be transferred to a java data class. Any ideas what could be wrong?
public class JSONimport extends AsyncTask<Void, Void, DeserializedContainer> {
private static final String TAG = "TAG";
//VARIABLES TO HOLD JSON DATA
private OnLoadListener mListener;
//CONSTRUCTOR
public JSONimport(OnLoadListener listener) {
this.mListener = listener;
}
//ASYNK, DO IN BACKGROUND THREAD
@Override
protected DeserializedContainer doInBackground(Void... voids) {
String myJSON = ""; //TEMP VARIABLE TO HOLD JSON DATA
String completeJSONdata = ""; //VARIABLE TO HOLD COMPLETE JSON DATA
try {
URL urlObject = new URL( "https://api.myjson.com/bins/161kkd" );
HttpURLConnection httpURLConnection = (HttpURLConnection) urlObject.openConnection();
InputStream inputStreamObject = httpURLConnection.getInputStream();
BufferedReader bufferedReaderObject = new BufferedReader( new InputStreamReader( inputStreamObject ) );
while (myJSON != null) {
myJSON = bufferedReaderObject.readLine();
completeJSONdata += myJSON;
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.d( TAG, "doInBackground: ERROR RETRIEVING URL" );
} catch (IOException e) {
e.printStackTrace();
Log.d( TAG, "doInBackground: ERROR HTTP CONNECTION" );
}
//DESERIALIZATION, converting JSON to java variables, making the data easy to handle
Gson gsonObject = new GsonBuilder()
.setLenient()
.create();
DeserializedContainer deserializedContainerObject;
deserializedContainerObject = gsonObject.fromJson( completeJSONdata, DeserializedContainer.class );
//Log.d( TAG, "doInBackground: " + deserializedContainerObject.getDeserializedContainerList() );
return deserializedContainerObject;
}
@Override
protected void onPostExecute(final DeserializedContainer result) {
mListener.onSuccess( result );
//FUNKAR ATT HÄMTA JSON DATA. KOLLA LOGCAT
Log.d( TAG, "onPostExecuteLOL: " + result );
}
public static interface OnLoadListener {
void onSuccess(DeserializedContainer container);
}}
The error is at deserializedContainerObject = gsonObject.fromJson( completeJSONdata, DeserializedContainer.class );
The data objects to hold the JSON data:
public class DeserializedContainer {
@SerializedName("deserializedContainerList")
public List<DeserializedVariables> deserializedContainerList = new ArrayList<>();
public List<DeserializedVariables> getDeserializedContainerList() {
return deserializedContainerList;
}}
public class DeserializedVariables {
@SerializedName( "movieName" )
private String movieName;
@SerializedName( "movieYear" )
private int movieYear;
@SerializedName( "movieRating" )
private double movieRating;}
Relevant data from the main thread:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
//BACKGROUND THREAD
JSONimport jsonImportObject = new JSONimport( new JSONimport.OnLoadListener() {
@Override
public void onSuccess(DeserializedContainer container) {
container.getDeserializedContainerList();
}
} );
jsonImportObject.execute();
//Log.d( TAG, "onCreateGETTING DATA : " + jsonImportObject.getCompletedData());
DeserializedContainer deserializedContainerObject = new DeserializedContainer();
Log.d( TAG, "onCreate: " + deserializedContainerObject);
JSON:
{"deserializedContainerList":[{"movieName":"filmA","movieYear":2017,"movieRating":4.7},{"movieName":"filmB","movieYear":2018,"movieRating":4.8},{"movieName":"filmC","movieYear":2019,"movieRating":4.9}]}
Sorry for such a long post, hope you have the energy to go through it. I'm really stuck. I know of Retrofit and similar libraries, but I have spent so many hours on getting this right that I don't want to abandon it just yet :P
Thanks!
/////// UPDATE /////// I updated the code according to Laurent B's suggestion, and it worked! Or, at least it didn't crash. I tried printing the list on the main thread with the following code:
for(int i = 0; i < deserializedContainerObject.deserializedContainerList.size(); i++) {
Log.d( TAG, "onCreate: " + deserializedContainerObject.deserializedContainerList.get( i ));
}
But nothing showed. When checking deserializedContainerObject.deserializedContainerList.size() it showed 0. That is, no data has been added to the list... Hmmm. At least it doesn't crash, thanks to Laurent B so one step closer.
onSuccess
methodDeserializedContainer container
?deserializedContainerObject
is declared outside of youronSuccess
method so it makes sense that it's list has a size of 0. – Sahib