How to make ViewModel display network data on first run - java

I am just getting into Android Architecture and have encountered an issue after following this tutorial by mitch:
ViewModel doesn't show any data from the internet- I'm using volley- on first run.
The UI remains blank and only shows data on the views only onChange. i.e A screen rotation/refresh
If I manually set this data, it shows them on first run as required
i.e dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","House 1","4345423232312","3224342434232") ); //Add data to the mutatable list
But once I include the network data, it misbehaves.
I have tried checking if my repository could be returning a null list on first run but the toast attached inside the repository shows that the data was well received, only that I dont understand why it wont display until either a change in screen rotation or a refresh
My Repository
public class GetHouseDetailsRepository {
private Context mContext;
private static final String URL_initializeDashboard= CustomFunctions.root_house_admin_url+"initialize_dashboard";
CustomFunctions func= new CustomFunctions();
private static GetHouseDetailsRepository instance;
private ArrayList<DecodeHouseDetails> dataSet= new ArrayList<>();
private JSONObject jsonObject;
public static GetHouseDetailsRepository getInstance(){
if(instance == null){
instance = new GetHouseDetailsRepository();
}
return instance;
}
//Make a mutable list of the data that we will be getting from the database
public MutableLiveData<List<DecodeHouseDetails>> getHouseDetails(Context mContext){
this.mContext=mContext;
getDatabaseHouseDetails();
MutableLiveData<List<DecodeHouseDetails>> myData= new MutableLiveData<>();
if(dataSet ==null){
getDatabaseHouseDetails();
}
myData.setValue(dataSet);
return myData;
}
//Method to actually get the data from the database
public void getDatabaseHouseDetails(){
//dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","Keja Mkononi","1","A nice house","Water,electrivit","Other amenities","5","1","Embu","1","1","1","1","4345423232312","3224342434232") ); //Add data to the mutatable list
jsonObject= new JSONObject();
try {
jsonObject.put("me",""+func.getSharedUserID(mContext) );//Logged in user
} catch (JSONException e) {
Log.e("JSONObject Here", e.toString());
}
VolleyNetworkRequestInterfaceSingleton.getResponse(mContext,Request.Method.GET, URL_initializeDashboard, jsonObject,new VolleyNetworkRequestInterfaceSingleton.VolleyCallback(){
#Override
public void onSuccessResponse(String response) {
if(response!=null) {
try {
JSONObject json = new JSONObject(response);
//Successfully fetched
String sarray = json.getString("house_details");
Toast.makeText(mContext, sarray, Toast.LENGTH_SHORT).show();
JSONArray jsonArray = new JSONArray(sarray);
//Clear list to refresh list in every selection
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json_list = jsonArray.getJSONObject(i);
DecodeHouseDetails houses_array = new DecodeHouseDetails(
json_list.getInt("active_identifier"),
json_list.getInt("house_id"),
json_list.getInt("house_status"),
json_list.getString("house_number"),
json_list.getString("house_cover"),
json_list.getString("house_name"),
json_list.getString("longitude"),
json_list.getString("latitude")
);
dataSet.add(houses_array);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
}
My ViewModel
public class GetHouseDetailsViewModel extends AndroidViewModel {
//The data we fetch from asynchronously
private MutableLiveData<List<DecodeHouseDetails>> mHouseDetailsList;
private GetHouseDetailsRepository mHouseDetailsRepository;
public GetHouseDetailsViewModel(#NonNull Application application) {
super(application);
}
public void init(){
if(mHouseDetailsList != null){
mHouseDetailsList= new MutableLiveData<>();
}
mHouseDetailsRepository = GetHouseDetailsRepository.getInstance(); //Initialize the repository
mHouseDetailsList = mHouseDetailsRepository.getHouseDetails(this.getApplication());
}
public LiveData<List<DecodeHouseDetails>> getHouseInfo() {
if(mHouseDetailsList == null){
mHouseDetailsList = new MutableLiveData<>();
}
return mHouseDetailsList;
}
}
My View - Fragment
public class AdmManageHouses extends Fragment {
private ProgressBar progressloader,progressloader_large;
SwipeRefreshLayout refreshLayout;
private TextView house_number_text,house_title_text,house_name_text;
private GetHouseDetailsViewModel mHouseDetailsViewModel;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_manage_houses, container, false);
mHouseDetailsViewModel = ViewModelProviders.of(getActivity()).get(GetHouseDetailsViewModel.class);
//Innitialize objects
house_title_text= rootView.findViewById(R.id.house_title);
house_number_text= rootView.findViewById(R.id.house_number);
house_name_text= rootView.findViewById(R.id.house_name);
//Initialize the view model
mHouseDetailsViewModel.init();
mHouseDetailsViewModel.getHouseInfo().observe(getViewLifecycleOwner(), new Observer<List<DecodeHouseDetails>>() {
#Override
public void onChanged(List<DecodeHouseDetails> decodeHouseDetails) {
for(int i=0; i<decodeHouseDetails.size(); i++) {
house_number_text.setText(String.valueOf(decodeHouseDetails.get(i).getHouse_number()));
house_title_text.setText(decodeHouseDetails.get(i).getHouse_name());
house_name_text.setText(decodeHouseDetails.get(i).getHouse_name());
}
}
});
//Refresh on swipe
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
initializeDashboard();
refreshLayout.setRefreshing(false);
}
});
initializeDashboard();
return rootView;
}
private void initializeDashboard() {
for(int i=0; i<mHouseDetailsViewModel.getHouseInfo().getValue().size(); i++) {
house_number_text.setText(String.valueOf(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_number()));
house_title_text.setText(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_name());
house_name_text.setText(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_name());
}
}
}

After thorough checking of the viewmodel, I discovered that problem was in the repository and not the viewModel. I was not calling setValue() properly.
This made the first run - when the list is null - fail to populate the UI until onChange.
I made the following changes to the repository
i.e
Declare myData variable
Private MutableLiveData<List<DecodeHouseDetails>> myData= new MutableLiveData<>();
//Make a mutable list of the data that we will be getting from the database
public MutableLiveData<List<DecodeHouseDetails>> getHouseDetails(Context mContext){
this.mContext=mContext;
getDatabaseHouseDetails();
return myData;
}
//Method to actually get the data from the database
public void getDatabaseHouseDetails(){
//dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","Keja Mkononi","1","A nice house","Water,electrivit","Other amenities","5","1","Embu","1","1","1","1","4345423232312","3224342434232") ); //Add data to the mutatable list
jsonObject= new JSONObject();
try {
jsonObject.put("me",""+func.getSharedUserID(mContext) );//Logged in user
} catch (JSONException e) {
Log.e("JSONObject Here", e.toString());
}
VolleyNetworkRequestInterfaceSingleton.getResponse(mContext,Request.Method.GET, URL_initializeDashboard, jsonObject,new VolleyNetworkRequestInterfaceSingleton.VolleyCallback(){
#Override
public void onSuccessResponse(String response) {
if(response!=null) {
try {
JSONObject json = new JSONObject(response);
//Successfully fetched
String sarray = json.getString("house_details");
Toast.makeText(mContext, sarray, Toast.LENGTH_SHORT).show();
JSONArray jsonArray = new JSONArray(sarray);
//Clear list to refresh list in every selection
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json_list = jsonArray.getJSONObject(i);
DecodeHouseDetails houses_array = new DecodeHouseDetails(
json_list.getInt("active_identifier"),
json_list.getInt("house_id"),
json_list.getInt("house_status"),
json_list.getString("house_number"),
json_list.getString("house_cover"),
json_list.getString("house_name"),
json_list.getString("longitude"),
json_list.getString("latitude")
);
dataSet.add(houses_array);
}
myData.setValue(dataSet);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}

Related

Cant get ArrayList from another class. Its always empty

im still Android beginner and new to Stackowerflow, i hope you will understand my problem. Im using Volley libary and Singleton class. I have JsonParser class which after parsing should return the filled list with objects.
public class JsonParse {
Context context;
public ArrayList<ParseItem> parseItemList = new ArrayList<>();
String json_url = "myurl";
public JsonParse(Context context) {
this.context = context;
}
public ArrayList<ParseItem> getList() {
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, json_url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
ParseItem parseItem = new ParseItem();
String naslov = jsonObject.getString("naslov");
String url = jsonObject.getString("url");
parseItem.setTitle(naslov);
parseItem.setUrl(url);
JSONArray niz = jsonObject.getJSONArray("niz");
ArrayList<String> podnaslovTMP = new ArrayList<>();
ArrayList<String> podurlTMP = new ArrayList<>();
for (int j = 0; j < niz.length(); j++) {
JSONObject nizOBJ = niz.getJSONObject(j);
String podnaslov = nizOBJ.getString("podnaslov");
String podurl = nizOBJ.getString("podurl");
podnaslovTMP.add(podnaslov);
podurlTMP.add(podurl);
}
parseItemList.add(parseItem);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
return parseItemList;
}}
Then im trying to call getList and take my list i HomeFragment.
public class HomeFragment extends Fragment implements View.OnClickListener {
private Context context;
private static final int REQUEST_CALL = 1;
private View view;
private ParseItem parseItem = new ParseItem();
public ArrayList<ParseItem>arrayList = new ArrayList<>();
public HomeFragment() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home, container, false);
init();
JsonParse jsonParse = new JsonParse(getActivity());
arrayList = jsonParse.getList();
return view;
}
My arrayList is always empty. I hope someone can help me.
create listner
public interface GetArrayListListner{
void getArrayData(ArrayList<ParseItem>);
}
and
public class JsonParse {
private GetArrayListListner arrayListListner;// add this line
Context context;
public ArrayList<ParseItem> parseItemList = new ArrayList<>();
String json_url = "myurl";
public JsonParse(Context context,GetArrayListListner arrayListListner) {
this.context = context;
this.arrayListListner = arrayListListner; //Add this line
}
public void getList() {
new JsonArrayRequest(Request.Method.POST, json_url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
ParseItem parseItem = new ParseItem();
String naslov = jsonObject.getString("naslov");
String url = jsonObject.getString("url");
parseItem.setTitle(naslov);
parseItem.setUrl(url);
JSONArray niz = jsonObject.getJSONArray("niz");
ArrayList<String> podnaslovTMP = new ArrayList<>();
ArrayList<String> podurlTMP = new ArrayList<>();
for (int j = 0; j < niz.length(); j++) {
JSONObject nizOBJ = niz.getJSONObject(j);
String podnaslov = nizOBJ.getString("podnaslov");
String podurl = nizOBJ.getString("podurl");
podnaslovTMP.add(podnaslov);
podurlTMP.add(podurl);
}
parseItemList.add(parseItem);
} catch (JSONException e) {
e.printStackTrace();
}
}
arrayListListner.getArrayData(parseItemList);//add this line
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
return parseItemList;
}
}
and call it
JsonParse jsonParse = new JsonParse(getActivity(),new GetArrayListListner(){
#Overrid void getArrayData(ArrayList<ParseItem>){
arrayList = jsonParse.getList();
}
});
Your method getList() calls a web service, which is executed on a separate thread. When you use MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
you are placing the request to a Queue, that means it is not gonna be executed right now, but you are already returning your array. As the request hasn't been executed yet, your array list hasn't been filled yet.
The practice recommended by Google today is using LiveData, it can be hard to a beginner, but with a little study, you can solve it.
https://developer.android.com/topic/libraries/architecture/livedata
Maybe you can look at Reactive Programming as well.
Another easy solution would be using interfaces, so you can pass the interface as a parameter, which will be triggered when your array gets filled.
Let me know if I was of any help, thanks

Populate data into spinner dynamically

I'm currently stuck on how I'm going to display my data to my spinner. So basically I am using Websocket to receive data and run it on my UI thread my problem is that there is no list of data showing in my spinner.
Here is my code:
WayPointData = new SubscribedData<>();
final Type WayPointType = new TypeToken<SubscribedData<WayPoint>>() {
}.getType();
/** an ID for the spinner **/
spin = (Spinner) findViewById(R.id.spinner);
final SpinnerAdapter adapter = new ArrayAdapter<String>(Pop.this, android.R.layout.simple_spinner_item);
spin.setAdapter(adapter);
rosbridge = new RosbridgeListener("ws://10.24.204.231:9090");
rosbridge.setOnDataReceivedListener(new RosbridgeMessageListener() {
/**
* a running thread that when the connection is made the data of the topic will serialize and deserialized java objects
* to (and from) JSON.
* #param msg
*/
#Override
public void onDataReceived(final String msg) {
try {
runOnUiThread( new Runnable() {
#Override
public void run() {
try {
WayPointData = new Gson().fromJson(msg,WayPointType);
JSONObject jsonObject = new JSONObject();
JSONArray wayPointJsonArray = jsonObject.getJSONObject("msg").getJSONArray("waypoints");
for (int i = 0; i < wayPointJsonArray.length(); i++) {
JSONObject wayPointJsonObject = wayPointJsonArray.getJSONObject(i);
// Parse name
String name = wayPointJsonObject.getString("name");
WayPoint wayPoint = new WayPoint();
wayPoint.name = name;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
/** a msg that will display once the data is received **/
Log.d("B9T", String.format("Received data: %s", msg));
} catch (Exception e) {
e.printStackTrace();
}
}
});
spin.setAdapter(adapter);
spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int p, long id) {
WayPoint wayPoint = (WayPoint) parent.getItemAtPosition(p);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Thanks to anyone who can help me!
add array when you initing your adapter:
final SpinnerAdapter adapter = new ArrayAdapter<String>(Pop.this, android.R.layout.simple_spinner_item, yourStringArray);
if you make changes later (will receive list from server) just setup array that you used before with new data and use adapter.notifyDataSetChanged()
Here I can see you don't pass json string to JSONObject that's why your main JSON object is an empty json object.
You should pass the JSON string to the JSONObject parameter like below.
JSONObject jsonObject = new JSONObject(msg); // here you have to add your json string in JSONObject parameter
Hope it helps you.

Don't update realmResult and not set TextView

I have 4 classes. I got some data from the JSON and wrote the realm. After that, in FilmFeature class, I insert some new values to realm but realmResult don't update and TextView comes to null.
Before this class, We have some information on RealmResult but this information not to "Type" or "imdbID"
FilmFeature Class:
JSONArray array1 = jsonObject2.getJSONArray("Search");
for (int i = 0; i < array1.length(); i++) {
final JSONObject film_ozel = array1.getJSONObject(i);
if(baslik_bilgisi.equals(film_ozel.getString("Title"))) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
film film_ozellik = realm.createObject(film.class);
try {
film_ozellik.setType(film_ozel.getString("Type"));
film_ozellik.setImdbID(film_ozel.getString("imdbID"));
realm.insertOrUpdate(film_ozellik);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
realmResult = realm.where(film.class).findAll();
tür.setText(realmResult.get(position).getType());
imdb.setText(realmResult.get(position).getImdbID());

Swipe Refresh freezes when executing async task

I'm encountering a problem, when I try running an asynchronous task on refresh using a swipe refresh layout it "freezes" and doesn't rotate. When the task is done it just disappears.
Here is my code:
HotActivityFragment.java:
public class HotActivityFragment extends Fragment {
ListView hotList;
SwipeRefreshLayout mSwipeRefreshLayout;
Context context;
SharedPreferences sharedPreferences;
HotListAdapter hotListAdapter;
public HotActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hot, container, false);
context = getContext();
mSwipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.activity_main_swipe_refresh_layout);
hotList = (ListView)view.findViewById(R.id.hotListView);
hotList.setOnScrollListener(new EndlessScrollListener(getActivity()));
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
try {
ArrayList<ListTypeItem> initial_list = new DownloadPosts(getActivity()).execute().get();
this.hotListAdapter = new HotListAdapter(getContext(), initial_list);
hotList.setAdapter(hotListAdapter);
}catch(Exception e)
{
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrievePosts();
}
});
mSwipeRefreshLayout.setColorSchemeResources(R.color.accentColor, R.color.backgroundColor);
return view;
}
public void retrievePosts()
{
// showing refresh animation before making http call
mSwipeRefreshLayout.setRefreshing(true);
//shared preferences = empty
sharedPreferences.edit().putString("last_time_downloaded", "empty").commit();
try {
ArrayList<ListTypeItem> listItems = new DownloadPosts(getActivity(), mSwipeRefreshLayout).execute().get();
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
} catch (Exception e) {
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setRefreshing(false);
//for testing purposes
// new Handler().postDelayed(new Runnable() {
// #Override public void run() {
// mSwipeRefreshLayout.setRefreshing(false);
// }
// }, 5000);
}
}
DownloadPosts.java:
public class DownloadPosts extends AsyncTask<Void, Void, ArrayList<ListTypeItem>> {
SharedPreferences sharedPreferences;
SwipeRefreshLayout swipeRefreshLayout;
public DownloadPosts(Activity activity)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
}
public DownloadPosts(Activity activity, SwipeRefreshLayout swipeRefreshLayout)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
this.swipeRefreshLayout = swipeRefreshLayout;
}
#Override
protected ArrayList<ListTypeItem> doInBackground(Void... args)
{
StringBuilder parsedString = new StringBuilder();
ArrayList<ListTypeItem> downloadList = new ArrayList<>();
StringBuilder str = new StringBuilder();
if(sharedPreferences.getBoolean("Thomas More",false))
{
str.append("190155257998823,");
}
String school_url = str.toString();
if(school_url.length() > 0)
{
school_url = school_url.substring(0, str.length()-1);
}
try{
String date = "";
//checken of opnieuw moet bepaald worden
// + in de adapter moet als gereload wordt last_time_downloaded == empty
if(!sharedPreferences.getString("last_time_downloaded","empty").equals("empty"))
{
String last_date = sharedPreferences.getString("last_time_downloaded","nothing");
last_date = last_date.replace(" ","T");
date= "&datum_last_posted=" + last_date;
}
URL url = new URL("http://localhost/getpostlist.php?school_post=" + school_url + date);
URLConnection conn = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String json;
while((json = bufferedReader.readLine())!= null)
{
parsedString.append(json + "/n");
}
String s = parsedString.toString().trim();
//converten van string opgehaald via http naar jsonobject
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++)
{
JSONObject tempObj = array.getJSONObject(i);
School_WithoutImage tempSchool = new School_WithoutImage(tempObj.getString("school_id"),
tempObj.getString("post_message"),tempObj.getInt("views"),tempObj.getInt("likes")
,tempObj.getInt("post_id"),tempObj.getString("datum_posted"));
downloadList.add(tempSchool);
if(i == array.length()-1) {
sharedPreferences.edit().putString("last_time_downloaded",tempObj.getString("datum_posted")).commit();
}
}
JSONObject obj = array.getJSONObject(0);
}catch(Exception e)
{
Log.d("Exception", e.toString());
}
return downloadList;
}
#Override
protected void onPostExecute(ArrayList<ListTypeItem> result)
{
if(this.swipeRefreshLayout != null)
{
// swipeRefreshLayout.setRefreshing(false);
}
}
}
I have no idea why the swiperefreshview doesn't spin. Anyone has an idea?
Because the call to get():
.execute().get()
Forces the UI thread to wait for the AsyncTask to finish.
Instead you should look at doing this in the onPostExecute method:
protected void onPostExecute(ArrayList<ListTypeItem> listItems) {
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
}
Because you are waiting for the result from asynctask by calling get just after execute. And further passing it to list.
You can use Local Broadcast Listener or can create an interface and can us that as callback, without freezing UI

Loop AsyncTask to fetch JSON and store as object in same list

I want to read and store all JSON values from this api Link with get request "Mini" as example (which is actually an user input variable) and the last number is the page your are viewing. Every page can hold a max of 50 results. The same link is also in XML format (I must read and store as JSON, this is for easier understanding)
In this exmaple there are 8 pages with a total of 359 results. I need to loop through all pages and add all the JSON values to the same object list.
I have the code which work to read one page. I do not know how to make it loop through all pages and add to same object list.
In the acitivty.java onCreate I call the AsyncTask.
String userSearchRequest = search_activity_data.getString("userSearchRequest");
int page = 0;
String spidy_iTN_url = "http://www.gw2spidy.com/api/v0.9/json/item-search/" + userSearchRequest + "/" + page;
itemsByInput_AsyncTask itemsByInput_AsyncTask = new itemsByInput_AsyncTask();
itemsByInput_AsyncTask.setItemListToListings(this);
itemsByInput_AsyncTask.execute(spidy_iTN_url);
This is my AsyncTask class called itemsByInput_AsyncTask.java
import constructors.itemResults_api_constr;
import constructors.itemRoot_api_constr;
public class itemsByInput_AsyncTask extends AsyncTask<String, Void, JSONObject> {
JSONObject Jo_result;
private itemListToListings itemListToListings;
public void setItemListToListings (itemListToListings itemListToListings) {
this.itemListToListings = itemListToListings;
}
#Override
protected JSONObject doInBackground(String... params) {
return spidyHttpGetRequest(params[0]);
}
public JSONObject spidyHttpGetRequest(String URL){
try {
HttpGet get = new HttpGet(URL);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
Jo_result = new JSONObject(result);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return Jo_result;
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
this.itemListToListings.itemListToListings(JoToJO_constructor(jsonObject));
}
public itemRoot_api_constr JoToJO_constructor(JSONObject Jo_result) {
itemRoot_api_constr spidy_iTN_rootO = new itemRoot_api_constr();
try {
spidy_iTN_rootO.setCount(Jo_result.getInt("count"));
spidy_iTN_rootO.setPage(Jo_result.getInt("page"));
spidy_iTN_rootO.setLast_page(Jo_result.getInt("last_page"));
spidy_iTN_rootO.setTotal(Jo_result.getInt("total"));
JSONArray list = new JSONArray(Jo_result.getString("results"));
for (int i = 0; i < spidy_iTN_rootO.getCount(); i++) {
JSONObject resultsObject = list.getJSONObject(i);
itemResults_api_constr spidy_iTN_resultsO = new itemResults_api_constr();
spidy_iTN_resultsO.setData_id(resultsObject
.getInt("data_id"));
spidy_iTN_resultsO.setName(resultsObject
.getString("name"));
spidy_iTN_resultsO.setRarity(resultsObject
.getInt("rarity"));
spidy_iTN_resultsO.setRestriction_level(resultsObject
.getInt("restriction_level"));
spidy_iTN_resultsO.setImg(resultsObject
.getString("img"));
spidy_iTN_resultsO.setType_id(resultsObject
.getInt("type_id"));
spidy_iTN_resultsO.setSub_type_id(resultsObject
.getInt("sub_type_id"));
spidy_iTN_resultsO.setPrice_last_changed(resultsObject
.getString("price_last_changed"));
spidy_iTN_resultsO.setMax_offer_unit_price(resultsObject
.getInt("max_offer_unit_price"));
spidy_iTN_resultsO.setMin_sale_unit_price(resultsObject
.getInt("min_sale_unit_price"));
spidy_iTN_resultsO.setOffer_availability(resultsObject
.getInt("offer_availability"));
spidy_iTN_resultsO.setSale_availability(resultsObject
.getInt("sale_availability"));
spidy_iTN_resultsO.setSale_price_change_last_hour(resultsObject
.getInt("sale_price_change_last_hour"));
spidy_iTN_resultsO.setOffer_price_change_last_hour(resultsObject
.getInt("offer_price_change_last_hour"));
spidy_iTN_rootO.addObject(spidy_iTN_resultsO);
}
} catch (JSONException e) {
e.printStackTrace();
}
return spidy_iTN_rootO;
}
public interface itemListToListings {
public void itemListToListings(itemRoot_api_constr resultClass);
}
}
And finally in my activity.java i can use my object in the method itemListToListings().
How can I make this loop through all pages (last_page property) and add all JSON values as object in the same list.
EDIT: My itemListToListings function in my activity.
public void itemListToListings(final itemRoot_api_constr spidy_iTN_construct) {
ArrayList<listItemWidgets_constr> image_details = getListData(spidy_iTN_construct);
final ListView lv1 = (ListView) findViewById(R.id.listView);
lv1.setAdapter(new itemListAdapter(this, image_details));
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//listItemWidgets_constr newsData = (listItemWidgets_constr) lv1.getItemAtPosition(position);
Toast.makeText(resultsActivity.this, "Selected :" + spidy_iTN_construct.results(position).name, Toast.LENGTH_LONG).show();
Intent i = new Intent(resultsActivity.this, listingsActivity.class);
i.putExtra("itemId", spidy_iTN_construct.results(position).data_id);
startActivity(i);
}
});
}
EDIT 3: error log
05-01 07:17:39.828 3620-3620/com.example.krijn.gw2TP_androidMobile E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.krijn.gw2TP_androidMobile, PID: 3620
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask$itemListToListings.itemListToListings(com.example.krijn.gw2TP_androidMobile.constructors.itemRoot_api_constr)' on a null object reference
at com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask.onProgressUpdate(itemsByInput_AsyncTask.java:88)
at com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask.onProgressUpdate(itemsByInput_AsyncTask.java:27)
After I get this error in the Logcat I still see the Log updating with the following in doInBackground
for (int n = 1; n < nPage; n++){
Log.i("gw2Log", "n: " + n);
publishProgress(JoToJO_constructor(spidyHttpGetRequest(makeUrl(n))));
}
After that is done looping the application crashes.
I think you want to make chain calls depending on last_page property you get from the first page. I would do somethig like this where upon each completion of a request the UI is updated on onProgressUpdate
public class itemsByInput_AsyncTask extends AsyncTask<Void, itemRoot_api_constr, Void> {
JSONObject Jo_result;
private itemListToListings itemListToListings;
String userSearchRequest;
public itemsByInput_AsyncTask(String userSearchRequest){
this.userSearchRequest = userSearchRequest;
}
private String makeUrl(int page){
return "http://www.gw2spidy.com/api/v0.9/json/item-search/" +
this.userSearchRequest + "/" + page;
}
#Override
protected Void doInBackground(Void... params) {
itemRoot_api_constr iac;
iac = JoToJO_constructor(spidyHttpGetRequest(makeUrl(0)));
nPage = iac.getLast_page();
publishProgress(iac);
for (int n = 1; n<nPage; n++){
publishProgress(spidyHttpGetRequest(makeUrl(n)));
}
return null;
}
#Override
protected void onProgressUpdate(itemRoot_api_constr... iacs) {
super.onProgressUpdate(iacs);
// assuming method itemListToListings updates UI
// if it doesn't then publishProgress and onProgressUpdate are not needed
// and itemListToListings can be done in doInBackground
this.itemListToListings.itemListToListings(iacs[0]);
}
#Override
protected Void onPostExecute(Void void) {
super.onPostExecute(void);
// unused
}
}
Also:
Adapter, views, and related click listeners should be initiated once. You should move all variables inside of itemListToListings as your Activity field so everytime this callback is called, they won't need to be initiated again.
ListView lv1;
ArrayList<listItemWidgets_constr> image_details = new ArrayList<>();
itemListAdapter adapter;
void onCreate(){
...
lv1 = (ListView) findViewById(R.id.listView);
adapter = new itemListAdapter(this, image_details);
lv1.setOnItemClickListener(...);
}
public void itemListToListings(final itemRoot_api_constr spidy_iTN_construct) {
image_details.clear();
image_details.addAll(getListData(spidy_iTN_construct));
adapter.notifyDataSetChanged();
}

Categories