I am implementing endless listview in Fragment. When I writes the code for setOnScrollListener for my listview then my app is crashing with the error The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. I have tried almost everything to apply notifyDataSetChanged() on my adapter. Please help me to solve the problem.
below is my code.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_all_campaign, container, false);
allCampaignList = (ListView) rootView.findViewById(R.id.allCampaignList);
adapter = new CampaignListAdapter(getActivity(), CampaignDataArrayList);
loadCampaignsData(offsetValue);
allCampaignList.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScroll(AbsListView view,
int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
//Algorithm to check if the last item is visible or not
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount) {
// you have reached end of list, load more data
loadCampaignsData(offsetValue + 1);
offsetValue++;
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//blank, not using this
}
});
return rootView;
}
Below is the method loadCampaignsData():
public void loadCampaignsData(final int offset) {
pDialog.setMessage("Please wait..");
pDialog.setTitle("Loading");
showDialog();
Handler h = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what != 1) {
hideDialog();// code if not connected
viewUtils.internertErrorMsgDialog();
} else {
GetAllCampaign getAllCampaign = new GetAllCampaign();
getAllCampaign.execute(String.valueOf(offset));
}
}
};
viewUtils.isNetworkAvailable(h, 2000); // get the answser within 2000 ms
}
Below is the asynctask written for fetching webservice.
private class GetAllCampaign extends AsyncTask<String, Void, ArrayList<HashMap<String, String>>> {
#Override
protected ArrayList<HashMap<String, String>> doInBackground(String... params) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(Constants.DADAMI_URL + Constants.ALL_CAMPAIGN);
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("cat_id", "0"));
list.add(new BasicNameValuePair("user_id", ""));
list.add(new BasicNameValuePair("offset", params[0]));
httpPost.setEntity(new UrlEncodedFormEntity(list));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
return readResponse(httpResponse);
//return null;
} catch (Exception exception) {
exception.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
super.onPostExecute(result);
hideDialog();
if (result == null) {
Toast.makeText(context, "Something went wrong.. Please try again..!!", Toast.LENGTH_LONG).show();
} else {
getActivity().runOnUiThread(new Runnable() {
public void run() {
allCampaignList.setAdapter(adapter);
}
});
}
}
}
private ArrayList<HashMap<String, String>> readResponse(HttpResponse res) {
InputStream is = null;
try {
is = res.getEntity().getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
JSONObject mainObj = new JSONObject(sb.toString());
JSONArray fundraiser_data = null;
fundraiser_data = mainObj.getJSONArray("fundraiser_data");
for (int i = 0; i < fundraiser_data.length(); i++) {
JSONObject elem = fundraiser_data.getJSONObject(i);
String fundraiser_photo = elem.getString("fundraiser_photo");
String title = elem.getString("title");
String fullname = elem.getString("fullname");
HashMap<String, String> campaignData = new HashMap<>();
campaignData.put("fundraiser_photo", Constants.DADAMI_IMAGE_URL + fundraiser_photo);
campaignData.put("title", title);
campaignData.put("fullname", fullname);
CampaignDataArrayList.add(campaignData);
}
} catch (Exception e) {
e.printStackTrace();
}
return CampaignDataArrayList;
}
Related
I am new in android. I am trying to fetch data in spinner from database. But I don't know why my list is not set in spinner.
My code is
public class AddBasicDetail extends Fragment implements AdapterView.OnItemSelectedListener {
// array list for spinner adapter
private ArrayList<State> categoriesList;
ProgressDialog pDialog;
Spinner sp_state;
// API urls
// Url to create new category
private String URL_NEW_CATEGORY = "http://mandirdekhoo.com/app/md_eng/state.php";
public AddBasicDetail() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.add_basic_detail, container, false);
sp_state = (Spinner) v.findViewById(R.id.sp_state);
categoriesList = new ArrayList<State>();
// spinner item select listener
//sp_state.setOnItemSelectedListener((AdapterView.OnItemSelectedListener) getActivity());
new GetCategories().execute();
return v;
}
/**
* Adding spinner data
* */
private void populateSpinner() {
List<String> lables = new ArrayList<String>();
//txtCategory.setText("");
for (int i = 0; i < categoriesList.size(); i++) {
lables.add(categoriesList.get(i).getName());
}
// Creating adapter for spinner
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
spinnerAdapter .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
sp_state.setAdapter(spinnerAdapter);
}
/**
* Async task to get all food categories
* */
private class GetCategories extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getContext());
pDialog.setMessage("Fetching food categories..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
ServiceHandler jsonParser = new ServiceHandler();
String json = jsonParser.makeServiceCall(URL_NEW_CATEGORY, ServiceHandler.GET);
Log.e("Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
Log.e("my response: ", "> " + jsonObj);
if (jsonObj != null) {
JSONArray categories = jsonObj .getJSONArray("result");
for (int i = 0; i < categories.length(); i++) {
JSONObject catObj = (JSONObject) categories.get(i);
State cat = new State(catObj.getInt("id"),
catObj.getString("state_name"));
categoriesList.add(cat);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
//populateSpinner();
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(
getContext(),
parent.getItemAtPosition(position).toString() + " Selected" ,
Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}
my service handler class is
public class ServiceHandler {
static InputStream is = null;
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/**
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/**
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
response = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error: " + e.toString());
}
return response;
}
}
and
public class State {
private int id;
private String name;
public State(){}
public State(int id, String name){
this.id = id;
this.name = name;
}
public void setId(int id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public int getId(){
return this.id;
}
public String getName(){
return this.name;
}
}
Please help
Hey after getting the correct response try to add this code
for e.g i am trying hardcoded values.replace this with your json.
final List<String> yourlist=new ArrayList<String>();
yourlist.add("Item 1");
yourlist.add("Item 2");
yourlist.add("Item 3");
yourlist.add("Item 4");
yourlist.add("Item 5");
final Spinner sp1= (Spinner) findViewById(R.id.spinner1);
final Spinner sp2= (Spinner) findViewById(R.id.spinner2);
ArrayAdapter<String> adp1=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,yourlist);
adp1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp1.setAdapter(adp1);
Hope this helps.:)
Change your method like this
private void populateSpinner(List<String> categoriesList) {
List<String> lables = new ArrayList<String>();
for (int i = 0; i < categoriesList.size(); i++) {
lables.add(categoriesList.get(i).getName());
}
// Creating adapter for spinner
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
spinnerAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
sp_state.setAdapter(spinnerAdapter);
}
And after calling this method notifydatasetchanged() call this method.
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
populateSpinner(categoriesList);
}
Hope this will help you
I'm new at android.I'm trying to develop a client app.Anyway,I have user profile activity which has friends and followers and counts are being showed with textview. When a user click on count of followers textview see friends list on dialog box as a listview. it is created an apiclient object for retrieving data as a json format from server.
friendsCountTxtView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyTApiClients apiclients = new MyApiClients(session);
apiclients.getFriendsListService().show(userID, userName, -1, countForList, new Callback<Response>() {
#Override
public void success(Result<Response> result) {
BufferedReader reader;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(result.response.getBody().in()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
String jsonResult = sb.toString();
try {
JSONObject objResult = new JSONObject(jsonResult);
nextCursor = Long.parseLong(objResult.getString("next_cursor"));
ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
listViewLoaderTask.execute(jsonResult);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void failure(Exception e) {
}
});
}
});
I used an asyncTask for parsing jsonobject and binding it listview.
private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter> {
JSONObject jObject;
/** Returning an Adapter For Using Post Execute*/
#Override
protected SimpleAdapter doInBackground(String... strJson) {
try{
jObject = new JSONObject(strJson[0]);
UserProfileJsonParser userProfileJsonParser = new UserProfileJsonParser();
userProfileJsonParser.parse(jObject);
}catch(Exception e){
Log.d("JSON Exception1", e.toString());
}
UserProfileJsonParser userProfileJsonParser = new UserProfileJsonParser();
List<HashMap<String, String>> userProfiles = null;
try{
/** Getting the parsed data as a List construct */
userProfiles = userProfileJsonParser.parse(jObject);
}catch(Exception e){
Log.d("Exception",e.toString());
}
/** Keys used in Hashmap */
String[] from = { "name","screen_name"};
/** Ids of views in listview_layout */
int[] to = { R.id.name,R.id.screen_name};
SimpleAdapter adapter = new SimpleAdapter(UserProfileActivity.this, userProfiles, R.layout.friends_list_items_layout, from, to);
return adapter;
}
/** Invoked by the Android system on "doInBackground" is executed completely */
/** This will be executed in ui thread */
#Override
protected void onPostExecute(final SimpleAdapter adapter) {
dialoglist.setAdapter(adapter);
builder.setView(dialoglist);
if (!isDialogBoxOpen)
{
isDialogBoxOpen = true;
final Dialog dialog = builder.create();
dialog.show();
}
}
}
Later when user scrolls listview it executes another async method for loading more data.
dialoglist.setOnScrollListener(new OnScrollListener() {
private int currentVisibleItemCount;
private int currentScrollState;
private int currentFirstVisibleItem;
private int totalItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int threshold = 1;
int count = dialoglist.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (dialoglist.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
new LoadMoreDataTask().execute();
}
}
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItem = totalItemCount;
}
private void isScrollCompleted() {
if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
&& this.currentScrollState == SCROLL_STATE_IDLE) {
/** To do code here*/
}
}
});
}
private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
MyApiClients apiclients = new MyApiClients(session);
apiclients.getFriendsListService().show(userID, userName, nextCursor, countForList, new Callback<Response>() {
#Override
public void success(Result<Response> result) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(result.response.getBody().in()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
String jsonResult = sb.toString();
try {
JSONObject objResult = new JSONObject(jsonResult);
nextCursor = Long.parseLong (objResult.getString("next_cursor"));
ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
listViewLoaderTask.execute(jsonResult);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void failure(Exception e) {
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
}
}
Lastly when we load more data i call listViewLoaderTask again for binding retrieved data from service.
It works but there some problems. When reminder data comes(5 row) dialog box become smaller.And sometimes when i click text view it isn't opened dialog box.
Question 1: How can i make my dialog box stable. is Custom dialog efficiency solution for this.
Question 2: I used async methods for this operations. Do you think that my usage right ? What best practice way do you advice for my this task ?
Maybe this is answered before but i couldnt find any identical solution to this but proposals. I am building an app in which i populate 4 ListViews from Mysql database through JSON. The work is being done at 4 fragments. The thing is that when i populate the 2 Lists from database and the other 2 just with some string array data everything works fine but when i try to populate all 4 of them at the same time then it crashes.
The Error:
01-04 11:27:25.405 3002-3017/com.order.app.order W/EGL_genymotion﹕ eglSurfaceAttrib not implemented
01-04 11:27:25.405 3002-3017/com.order.app.order W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa31ff7a0, error=EGL_SUCCESS
01-04 11:27:30.619 3002-3002/com.order.app.order I/Choreographer﹕ Skipped 307 frames! The application may be doing too much work on its main thread.
My Fragment:
private View rootView;
private ListView lv;
private ArrayAdapter<ProductList> adapter;
private String jsonResult;
private String url = "http://reservations.cretantaxiservices.gr/files/getkafedes.php";
ProgressDialog pDialog;
List<ProductList> customList;
private TextView tv1, tv2;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_coffees_fragment, container, false);
lv = (ListView)rootView.findViewById(R.id.coffeesListView);
final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.activity_main_swipe_refresh_layout);
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(getActivity().getApplicationContext().CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean network_connected = activeNetwork != null && activeNetwork.isAvailable() && activeNetwork.isConnectedOrConnecting();
if (!network_connected) {
onDetectNetworkState().show();
} else {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
accessWebService();
registerCallClickBack();
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
accessWebService();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
}
return rootView;
}
private AlertDialog onDetectNetworkState() {
AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity().getApplicationContext());
builder1.setMessage(R.string.wifi_off_message)
.setTitle(R.string.wifi_off_title)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
getActivity().finish();
}
})
.setPositiveButton(R.string.action_settings,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
startActivityForResult((new Intent(
Settings.ACTION_WIFI_SETTINGS)), 1);
getActivity().finish();
}
});
return builder1.create();
}
private void registerCallClickBack() {
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity().getApplicationContext(), "You have chosen " + customList.get(position).getName(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (pDialog.isShowing()) {
pDialog.show();
} else {
pDialog.dismiss();
}
if (onDetectNetworkState().isShowing()
&& onDetectNetworkState() != null) {
onDetectNetworkState().show();
} else {
onDetectNetworkState().dismiss();
}
}
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (pDialog.isShowing()) {
pDialog.show();
} else {
pDialog.dismiss();
}
if (onDetectNetworkState().isShowing()) {
onDetectNetworkState().show();
} else {
onDetectNetworkState().dismiss();
}
}
}
public class JsonReadTask extends AsyncTask<String, Void, String> {
public JsonReadTask() {
super();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setTitle(R.string.waiting);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setMessage(getString(R.string.get_stocks));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.setInverseBackgroundForced(true);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
} catch (Exception e) {
getActivity().finish();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (Exception e) {
getActivity().finish();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
ListDrawer();
pDialog.dismiss();
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
task.execute(new String[]{url});
}
public void ListDrawer() {
customList = new ArrayList<ProductList>();
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("name");
String price = jsonChildNode.optString("price");
String image = jsonChildNode.optString("image");
customList.add(new ProductList(image, name, price));
}
} catch (Exception e) {
getActivity().finish();
}
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
As a matter of fact i am using 4 AsyncTasks to do this job. Any ideas???
EDIT:
I updated the code since i found something online but still the same error
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(customList == null){
accessWebService();
}else{
ListDrawer();
}
}
Any Help will be appreciated!!!
Here in this method you are actully in the UI thread
#Override
protected void onPostExecute(String result) {
ListDrawer();
pDialog.dismiss();
}
And you calling the ListDrawer(); method and it's going to do a CPU intensive task, parsing the JSON.
It throws an exception in that method and calls this getActivity().finish(); in the catch block. That's why you getting back to your previous activity.
Try parsing your JSON in the AsynckTask and it solves your problem for sure.
Update:
private View rootView;
private ListView lv;
private ArrayAdapter<ProductList> adapter;
private String jsonResult;
private String url = "http://reservations.cretantaxiservices.gr/files/getkafedes.php";
ProgressDialog pDialog;
List<ProductList> customList;
private TextView tv1, tv2;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_coffees_fragment, container, false);
lv = (ListView)rootView.findViewById(R.id.coffeesListView);
final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.activity_main_swipe_refresh_layout);
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(getActivity().getApplicationContext().CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean network_connected = activeNetwork != null && activeNetwork.isAvailable() && activeNetwork.isConnectedOrConnecting();
if (!network_connected) {
onDetectNetworkState().show();
} else {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
accessWebService();
registerCallClickBack();
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
accessWebService();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
}
return rootView;
}
private AlertDialog onDetectNetworkState() {
AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity().getApplicationContext());
builder1.setMessage(R.string.wifi_off_message)
.setTitle(R.string.wifi_off_title)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
getActivity().finish();
}
})
.setPositiveButton(R.string.action_settings,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
startActivityForResult((new Intent(
Settings.ACTION_WIFI_SETTINGS)), 1);
getActivity().finish();
}
});
return builder1.create();
}
private void registerCallClickBack() {
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity().getApplicationContext(), "You have chosen " + customList.get(position).getName(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (pDialog.isShowing()) {
pDialog.show();
} else {
pDialog.dismiss();
}
if (onDetectNetworkState().isShowing()
&& onDetectNetworkState() != null) {
onDetectNetworkState().show();
} else {
onDetectNetworkState().dismiss();
}
}
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (pDialog.isShowing()) {
pDialog.show();
} else {
pDialog.dismiss();
}
if (onDetectNetworkState().isShowing()) {
onDetectNetworkState().show();
} else {
onDetectNetworkState().dismiss();
}
}
}
public class JsonReadTask extends AsyncTask<String , Void, List<ProductList>> {
public JsonReadTask() {
super();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setTitle(R.string.waiting);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setMessage(getString(R.string.get_stocks));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.setInverseBackgroundForced(true);
pDialog.show();
}
#Override
protected List<ProductList> doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
customList = new ArrayList<ProductList>();
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("name");
String price = jsonChildNode.optString("price");
String image = jsonChildNode.optString("image");
customList.add(new ProductList(image, name, price));
}
return customList;
} catch (Exception e) {
e.printStackTrace();
getActivity().finish();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (Exception e) {
getActivity().finish();
}
return answer;
}
#Override
protected void onPostExecute(List<ProductList> customList) {
if(customList == null){
Log.d("ERORR", "No result to show.");
return;
}
ListDrawer(customList);
pDialog.dismiss();
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
task.execute(new String[]{url});
}
public void ListDrawer(List<ProductList> customList) {
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
You are accessing the field:
private String jsonResult;
from both background thread (in doInBackground methods of your AsyncTasks) and from UI thread in ListDrawer() method in the line:
JSONObject jsonResponse = new JSONObject(jsonResult);
The most likely cause of your crash is that the UI thread doesn't see that the jsonResult value was set (since the field isn't volatile) and creating of new JSONObject throws an exception.
The solution would be to perform the parsing of the response in the doInBackground() method of your async task and return ArrayList from it (EDIT: fixed compile errors)
#Override
protected ArrayList<ProductList> doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
String jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
ArrayList<ProductList> customList = new ArrayList<ProductList>();
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("name");
String price = jsonChildNode.optString("price");
String image = jsonChildNode.optString("image");
customList.add(new ProductList(image, name, price));
}
return customList;
} catch (Exception e) {
return null;
}
}
onPostExecute() method should be modified:
#Override
protected void onPostExecute(ArrayList<ProductList> result) {
pDialog.dismiss();
if(result == null) {
getActivity().finish();
} else {
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
}
finally the signature of your AsyncTask has to be changed:
public class JsonReadTask extends AsyncTask<ArrayList<ProductList>, Void, String> {
...
}
On the auto load, I need to be able to load more items from the URL. Where I am getting my Data via Json.
in my API call class I need to add to this nuber 10 as:
pairs.add(new BasicNameValuePair("limit", "10"));
Whenever the list view finish loading the currently data, then changes the value above and check again.
I though I needed to create a method in PaginationDemoActivity where it check for if more pages, then use intent to pass a new variable to overwrite ("limit", "10")) in the JSONfunctions class
Any advice ? Thanks guys
JSONfunctions
public class JSONfunctions extends Activity{
public static JSONObject getJSONfromURL(String url) {
InputStream is = null;
String result = "";
JSONObject jArray = null;
// Download JSON data from URL
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
//Add URL Encoding by sending post data
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("c","getlist"));
pairs.add(new BasicNameValuePair("page","1"));
pairs.add(new BasicNameValuePair("limit", "10"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,HTTP.UTF_8);
httppost.setEntity(entity);
// end Add URL Encoding by sending post data
HttpResponse httpResponse = httpclient.execute(httppost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
//end test
/*
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
*/
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// Convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
try {
jArray = new JSONObject(result);
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
return jArray;
}
}
Data
public class Data {
static String URL = " my api url";
static String itemsPerPage = "20";
public static final String TAG = Data.class.getSimpleName();
public static List<Pair<String, List<Composer>>> getAllData() {
List<Pair<String, List<Composer>>> res = new ArrayList<Pair<String, List<Composer>>>();
for (int i = 0; i < 4; i++) {
res.add(getOneSection(i));
}
return res;
}
public static List<Composer> getFlattenedData() {
List<HashMap<String, String>> arraylist;
JSONObject jsonobject;
JSONArray jsonarray;
List<Composer> res = new ArrayList<Composer>();
//Pair<String, List<Composer>> mydata;
arraylist = new ArrayList<HashMap<String, String>>();
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions.getJSONfromURL(URL);
Log.e("check", jsonobject.toString());
try {
// Locate the array name in JSON
jsonarray = jsonobject.getJSONArray("data");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
// Retrive JSON Objects
map.put("id", jsonobject.getString("id"));
map.put("title", jsonobject.getString("title"));
map.put("s_desc", jsonobject.getString("s_desc"));
map.put("img", jsonobject.getString("img"));
// Set the JSON Objects into the array
arraylist.add(map);
Composer s = new Composer(
jsonobject.getString("title"),
jsonobject.getString("s_desc"),
jsonobject.getString("id"),
jsonobject.getString("img"));
res.add(s);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return res;
}
protected void updateUrlItems()
{
}
public static Pair<Boolean, List<Composer>> getRows(int page) {
List<Composer> flattenedData = getFlattenedData();
if (page == 1) {
return new Pair<Boolean, List<Composer>>(true, flattenedData.subList(0, 5));
} else {
SystemClock.sleep(2000); // simulate loading
return new Pair<Boolean, List<Composer>>(page * 5 < flattenedData.size(),
flattenedData.subList((page - 1) * 5, Math.min(page * 5, flattenedData.size())));
}
}
public static Pair<String, List<Composer>> getOneSection(int index) {
String[] titles = {"", "", "", ""};
Composer[][] composerss = {
{
new Composer("", "", "", ""),
},
};
return new Pair<String, List<Composer>>(titles[index], Arrays.asList(composerss[index]));
}
}
PaginationDemoActivity
public class PaginationDemoActivity extends Activity {
AmazingListView lsComposer;
PaginationComposerAdapter adapter;
ImageLoader imageLoader;
// Flag for current page
static Integer current_page = 10;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pagination_demo);
imageLoader = new ImageLoader(this);
lsComposer = (AmazingListView) findViewById(R.id.lsComposer);
lsComposer.setLoadingView(getLayoutInflater().inflate(R.layout.loading_view, null));
lsComposer.setAdapter(adapter = new PaginationComposerAdapter());
adapter.notifyMayHaveMorePages();
}
public void bRefresh_click(View v) {
adapter.reset();
adapter.resetPage();
adapter.notifyMayHaveMorePages();
}
class PaginationComposerAdapter extends AmazingAdapter {
List<Composer> list = Data.getRows(1).second;
private AsyncTask<Integer, Void, Pair<Boolean, List<Composer>>> backgroundTask;
public void reset() {
if (backgroundTask != null) backgroundTask.cancel(false);
list = Data.getRows(1).second;
notifyDataSetChanged();
}
#Override
public int getCount() {
return list.size();
}
#Override
public Composer getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
protected void onNextPageRequested(int page) {
Log.d(TAG, "Got onNextPageRequested page=" + page);
if (backgroundTask != null) {
backgroundTask.cancel(false);
}
backgroundTask = new AsyncTask<Integer, Void, Pair<Boolean, List<Composer>>>() {
#Override
protected Pair<Boolean, List<Composer>> doInBackground(Integer... params) {
int page = params[0];
Log.e("more page", "page: " + page);
return Data.getRows(page);
}
#Override
protected void onPostExecute(Pair<Boolean, List<Composer>> result) {
if (isCancelled()) return;
Log.e("onPostExecute", "result: " + result.first);
list.addAll(result.second);
nextPage();
notifyDataSetChanged();
if (result.first) {
// still have more pages
notifyMayHaveMorePages();
} else {
notifyNoMorePages();
}
};
}.execute(page);
}
#Override
protected void bindSectionHeader(View view, int position, boolean displaySectionHeader) {
}
#Override
public View getAmazingView(int position, View convertView, ViewGroup parent) {
View res = convertView;
if (res == null) res = getLayoutInflater().inflate(R.layout.item_composer, null);
// we don't have headers, so hide it
res.findViewById(R.id.header).setVisibility(View.GONE);
TextView lName = (TextView) res.findViewById(R.id.lName);
TextView lYear = (TextView) res.findViewById(R.id.lYear);
TextView lId = (TextView) res.findViewById(R.id.lId);
// Locate the ImageView in listview_item.xml
ImageView lImg = (ImageView) res.findViewById(R.id.lImg);
Composer composer = getItem(position);
lName.setText(composer.name);
lYear.setText(composer.year);
lId.setText(composer.id);
Log.e("getAmazingView PRINT THE URL 1111111111", "URL: " + composer.img);
// Capture position and set results to the ImageView
// Passes img images URL into ImageLoader.class
imageLoader.DisplayImage(composer.img, lImg);
Log.e("222","333");
//khen
lsComposer.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// TODO Auto-generated method stub
if(id > -1){
Composer composer = adapter.getItem(position);
Intent intent = new Intent();
intent.setClass(getApplicationContext(), SingleItemView.class);
Bundle bundle = new Bundle();
bundle.putString("id", composer.id);
bundle.putString("name", composer.name);
bundle.putString("year", composer.year);
bundle.putString("img", composer.img);
intent.putExtras(bundle);
startActivity(intent);
}
}
});
//end khen
return res;
}
#Override
public void configurePinnedHeader(View header, int position, int alpha) {
}
#Override
public int getPositionForSection(int section) {
return 0;
}
#Override
public int getSectionForPosition(int position) {
return 0;
}
#Override
public Object[] getSections() {
return null;
}
}
}
Everything was fine until I used doInBackground(Object... arg0) inorder to show ProgressDialog until it is loaded then dismisses it on onPostExecute(Object result) method. No error message in a LogCat, just crashes. Please help?
Vacancy.java
package com.apps.vacancy;
//all the necessary imports are imported
public class Vacancy extends Activity {
public static String urlPageNumHolder;
public ProgressDialog dialog;
ListView lisView1;
EditText inputText;
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vacancy);
lisView1 = (ListView) findViewById(R.id.listView1);
inputText = (EditText) findViewById(R.id.editText1);
// Permission StrictMode
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
final Button btn1 = (Button) findViewById(R.id.button1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
searchJob();
}
});
}
public void searchJob() {
new LoadContentFromServer().execute();
dialog = ProgressDialog.show(this, "Vacancy", "Loading...", true, false);
}
public String getJSONUrl(String url, List<NameValuePair> params) {
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Download OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
} else {
Log.e("Log", "Failed to download file..");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
class LoadContentFromServer extends AsyncTask<Object, Integer, Object> {
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Object... arg0) {
String url = "http://10.0.2.2/android/smartaddis/mobile/vacancy/getVacancy.php";
// Paste Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("txtKeyword", inputText.getText().toString()));
try {
JSONArray data = new JSONArray(getJSONUrl(url, params));
final ArrayList<HashMap<String, String>> MyArrList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map;
for (int i = 0; i < data.length(); i++) {
JSONObject c = data.getJSONObject(i);
map = new HashMap<String, String>();
map.put("id", c.getString("id"));
map.put("title_en", c.getString("title_en"));
map.put("description_en", c.getString("description_en"));
map.put("posteddate", c.getString("posteddate"));
map.put("expiredate", c.getString("expiredate"));
MyArrList.add(map);
}
lisView1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> myAdapter, View myView,
int position, long mylng) {
urlPageNumHolder = MyArrList.get(position).get("id").toString();
Intent subActivity = new Intent(Vacancy.this,
VacancyWebber.class);
Bundle translateBundle = ActivityOptions
.makeCustomAnimation(Vacancy.this,
R.anim.slide_in_left, R.anim.slide_out_left).toBundle();
startActivity(subActivity, translateBundle);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
return MyArrList;
}
#Override
protected void onPostExecute (ArrayList<HashMap<String, String>> result) {
if (dialog != null)
dialog.dismiss();
SimpleAdapter sAdap = new SimpleAdapter(Vacancy.this, result,
R.layout.vacancy_column, new String[] { "title_en",
"description_en", "posteddate", "expiredate" }, new int[] { R.id.jobtitle,
R.id.jobdescription, R.id.jobdateTime, R.id.jobexpiredate });
lisView1.setAdapter(sAdap);
}
}
#Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
}
}
You are updating ui from doInbackground which you should not do. Return the result in doInbackground and update ui in onPostExecute.
In doInbackground return MyArrList. The result of background computation is a passed to onPostExecute.
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Object... params) {
// TODO Auto-generated method stub
ArrayList<HashMap<String, String>> MyArrList = new ArrayList<HashMap<String, String>>();
... // rest of the code
return MyArrList;
}
In onPostExecute initialize adapter and set the adapter to listview.
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// dimiss dialog
SimpleAdapter sAdap = new SimpleAdapter(Vacancy.this, result,
R.layout.vacancy_column, new String[] { "title_en",
"description_en", "posteddate", "expiredate" }, new int[] { R.id.jobtitle,
R.id.jobdescription, R.id.jobdateTime, R.id.jobexpiredate });
lisView1.setAdapter(sAdap);
... // rest of the code
}
For more info
http://developer.android.com/reference/android/os/AsyncTask.html
You also need to move the below inside onCreate after setContentView coz findViewById looks for a view in the current inflated layout.
ListView lisView1;
EditText inputText;
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vacancy);
lisView1 = (ListView) findViewById(R.id.listView1);
inputText = (EditText) findViewById(R.id.editText1);