Load data from json to list view - android

I have an application which load data from json to android as below
public class MainActivity extends Activity {
private final String URL_SERVICE = "http://92.253.101.239:81/sudandoctors/api.aspx?op=5&GovernorateId=&SpecializationId=&DoctorName=&LastDoctorId=0";
private final String URL_IMAGE_BASE = "http://92.253.101.239:81/sudandoctors/UploadedFiles/";
TextView tv;
DoctorInfo doctorObj = new DoctorInfo();
ArrayList<DoctorInfo> doctorsInfoList = new ArrayList<DoctorInfo>();
ListView lv = (ListView)findViewById(R.id.mylist);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncHttpClient client = new AsyncHttpClient();
client.get(URL_SERVICE, new AsyncHttpResponseHandler() {
#Override
public void onStart() {
super.onStart();
// show loading bar
Log.d("onStart", "onStart");
}
#Override
public void onSuccess(String response) {
super.onSuccess(response);
Log.d("onSuccess", "onSuccess");
DoctorsModel doctorModel = new DoctorsModel();
ArrayList<DoctorInfo> doctorsInfoList = new ArrayList<DoctorInfo>();
try {
// convert response to JSON
JSONObject json = new JSONObject(response);
// get JSON Items
doctorModel.setDoctorCnt(json.getInt("DoctorsCount"));
doctorModel.setOp(json.getString("op"));
JSONArray doctorsArray = json.getJSONArray("Doctors");
Log.d("dr arrat", doctorsArray.toString());
for (int i = 0; i < doctorsArray.length(); i++) {
JSONObject doctorJSON = doctorsArray.getJSONObject(i);
doctorObj .setId(doctorJSON.getString("Id"));
Log.d("id", doctorJSON.getString("Id"));
doctorObj.setName(doctorJSON.getString("DoctorName"));
doctorObj.setGovernorateId(doctorJSON.getString("GovernorateId"));
doctorObj.setGovernorateName(doctorJSON.getString("GovernorateName"));
doctorObj.setSpecializationName(doctorJSON.getString("SpecializationName"));
doctorObj.setHospitalId(doctorJSON.getString("HospitalId"));
doctorObj.setHospitalName(doctorJSON.getString("HospitalName"));
doctorObj.setImageName(URL_IMAGE_BASE + doctorJSON.getString("ImageName"));
doctorObj.setMobile(doctorJSON.getString("Mobile"));
doctorObj.setSpecializationId(doctorJSON.getString("SpecializationId"));
doctorObj.setWeekendDays(doctorJSON.getString("WeekendDays"));
doctorObj.setWorkingDays(doctorJSON.getString("WorkingDays"));
doctorObj.setWorkingTime(doctorJSON.getString("WorkingTime"));
doctorsInfoList.add(doctorObj);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable e, String message) {
super.onFailure(e, message);
// show error message
}
#Override
public void onFinish() {
super.onFinish();
// remove loading bar
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.activity_list_item);
// Assign adapter to ListView
lv.setAdapter(adapter);
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
And I want to show the data in list view, how can I do that ?

Use an Adapter - http://developer.android.com/reference/android/widget/Adapter.html
Create an adapter with your data, then set that adapter as the ListView's adapter.

Related

Android - RecyclerView NullPointerException getItemCount?

I have a recyclerView that it get me crash :
Here is my StartActivity :
public class StartActivity extends AppCompatActivity {
TextView txtTest;
private ProgressDialog pDialog;
// These tags will be used to cancel the requests
private String tag_json_obj = "jobj_req", tag_json_arry = "jarray_req";
private RecyclerView.Adapter mAdapter;
RecyclerView UserCode_Recycler;
private LinearLayoutManager mLayoutManager;
List<Marketing_Code> userCodeList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
txtTest = (TextView) findViewById(R.id.txtTest);
UserCode_Recycler = (RecyclerView) findViewById(R.id.UserCode_Recycler);
pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
if (fab != null) {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
makeJsonArryReq();
userCodeList = new ArrayList<>();
// create an Object for Adapter
mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this);
// set the adapter object to the Recyclerview
UserCode_Recycler.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
UserCode_Recycler.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
// use a linear layout manager
UserCode_Recycler.setLayoutManager(mLayoutManager);
}
private void showProgressDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideProgressDialog() {
if (pDialog.isShowing())
pDialog.hide();
}
/**
* Making json array request
*/
private void makeJsonArryReq() {
showProgressDialog();
JsonArrayRequest req = new JsonArrayRequest(Const.Marketing_List,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("MYData", response.toString());
userCodeList = MarketingCode_JSONParser.parseFeed(response.toString());
/* // create an Object for Adapter
mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this);
// set the adapter object to the Recyclerview
Search_Recycler.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
//txtTest.setText(response.toString());*/
mAdapter.notifyDataSetChanged();
hideProgressDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Custom Log Error", "Error: " + error.getMessage());
hideProgressDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req, tag_json_arry);
// Cancelling request
// ApplicationController.getInstance().getRequestQueue().cancelAll(tag_json_arry);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And my adapter :
public class UserCodeList_Adapter extends RecyclerView.Adapter<UserCodeList_Adapter.ViewHolder> {
private List<Marketing_Code> ucList;
public static Activity activity;
public UserCodeList_Adapter(List<Marketing_Code> userCodeList, Activity activity) {
this.ucList = userCodeList;
this.activity = activity;
}
#Override
public UserCodeList_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.listmarketing_cardview, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(UserCodeList_Adapter.ViewHolder viewHolder, int position) {
String userCode =String.valueOf(ucList.get(position).getMarketCode());
viewHolder.txtUserID.setText(userCode);
}
#Override
public int getItemCount() {
return ucList.size();
//return ucList == null ? 0 : ucList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtUserID;
public Marketing_Code items;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtUserID = (TextView) itemLayoutView.findViewById(R.id.txtUserID);
// Onclick event for the row to show the data in toast
itemLayoutView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
}
You haven't initialized your userCodeList.
Seeing your code, you based your adapter to that list while it is not yet initialized. Consequently, when the adapter tried to learn how much item your list have it throws a NullPointerException.
Change your declaration of userCodeList to one like below:
List<Marketing_Code> userCodeList = new ArrayList<>();
Seeing your updated question, you seem to base your data from a JSON response. If that's the case, what you're currently doing is almost correct.
Observe this slightly modified snippet of your code:
private void makeJsonArryReq() {
showProgressDialog();
JsonArrayRequest req = new JsonArrayRequest(Const.Marketing_List,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("MYData", response.toString());
/* YOUR OLD CODE -> */ // userCodeList = MarketingCode_JSONParser.parseFeed(response.toString());
/* HOW IT SHOULD'VE BEEN */ userCodeList.addAll(MarketingCode_JSONParser.parseFeed(response.toString()));
mAdapter.notifyDataSetChanged();
hideProgressDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Custom Log Error", "Error: " + error.getMessage());
hideProgressDialog();
}
});
// ...
Look at the commented part of the above snippet. Doing so should solve your problem and make the data visible on screen.
Two ways to handle this:
You need to check if the list is NULL before requesting to check its size
public int getItemCount () {
if(ucList == null)
return 0;
return ucList.size();
}
Alternatively, and this is the recommended approach to this matter, is to initialise it to an empty list at the start or make sure that it is always initialised before it is accessed by the associated adapter.
List<Marketing_Code> userCodeList = new ArrayList<>();
Hope this helps.
I think you need to use replaceAll function for the list ,instead of directly equating.
Here
userCodeList = MarketingCode_JSONParser.parseFeed(response.toString());
Try checking if userCodeList contains any data before initialzing the adapter.
Please do the following and try
// create an Object for Adapter
userCodeList = new ArrayList<>();
mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this);

Why is this implementation of parcelables to save and restore Custom Arraylist not Working

I am fetching data from json with Volley and populating RecyclerView with the parsed data but I ran into a bit of problem:
The call to get the items is in onCreate method, so the call is repeated each time the activity is recreated both from configuration changes and otherwise; hence the data is reloaded. So I found this answer that uses parcelables
and this article on Codepath (still on parcelables). After I have followed the instructions explicitly (or so I feel), there seems to be no change: the call to get data is repeated each time the activity is recreated.
FruitItems
public class FruitItems implements Parcelable {
private String fruit_title;
private String fruit_description;
private String fruit_image;
public String getFruit_title() {
return fruit_title;
}
public void setFruit_title(String fruit_title) {
this.fruit_title = fruit_title;
}
public String getFruit_description() {
return fruit_description;
}
public void setFruit_description(String fruit_description) {
this.fruit_description = fruit_description;
}
public String getFruit_image() {
return fruit_image;
}
public void setFruit_image(String fruit_image) {
this.fruit_image = fruit_image;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.fruit_title);
dest.writeString(this.fruit_description);
dest.writeString(this.fruit_image);
}
public FruitItems() {
}
protected FruitItems(Parcel in) {
this.fruit_title = in.readString();
this.fruit_description = in.readString();
this.fruit_image = in.readString();
}
public static final Parcelable.Creator<FruitItems> CREATOR = new Parcelable.Creator<FruitItems>() {
#Override
public FruitItems createFromParcel(Parcel source) {
return new FruitItems(source);
}
#Override
public FruitItems[] newArray(int size) {
return new FruitItems[size];
}
};
}
MainActivity
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
private final String KEY_POST_ITEMS = "fruititems";
//List of fruits
private List<FruitItems> mFruitItemsList;
//Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate called");
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.fruit_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_POST_ITEMS)) {
mFruitItemsList = savedInstanceState.getParcelableArrayList(KEY_POST_ITEMS);
} else {
//Initializing the fruitlist
mFruitItemsList = new ArrayList<>();
if (NetworkCheck.isAvailableAndConnected(this)) {
getData();
} else {
final Context mContext;
mContext = this;
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(R.string.alert_titl);
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setIcon(R.mipmap.ic_launcher);
alertDialogBuilder.setMessage(R.string.alert_mess);
alertDialogBuilder.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (!NetworkCheck.isAvailableAndConnected(mContext)) {
alertDialogBuilder.show();
} else {
getData();
}
}
});
alertDialogBuilder.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialogBuilder.show();
}
}
adapter = new FruitAdapter(mFruitItemsList, this);
recyclerView.setAdapter(adapter);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(KEY_POST_ITEMS, ArrayList<? extends Parcelable>))mFruitItemsList);
super.onSaveInstanceState(savedInstanceState);
}
//Getting json data
private void getData(){
Log.d(TAG, "getData called");
//Show progress dialog
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setCancelable(false);
mProgressDialog.setMessage(this.getResources().getString(R.string.load_fruit));
mProgressDialog.show();
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigFruit.GET_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
if (mProgressDialog != null) {
mProgressDialog.hide();
}
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//parsing json data
private void parseData(JSONArray array){
Log.d(TAG, "Parsing array");
for(int i = 0; i<array.length(); i++) {
FruitItems fruitItem = new FruitItems();
JSONObject jsonObject = null;
try {
jsonObject = array.getJSONObject(i);
fruitItem.setFruit_title(jsonObject.getString(ConfigFruit.TAG_POST_TITLE));
fruitItem.setFruit_description(jsonObject.getString(ConfigFruit.TAG_POST_DESCRIPTION));
//Parsing image
JSONObject fruitImage = jsonObject.getJSONObject("thumbnail");
fruitItem.setFruit_image(fruitImage.getString("url"));
} catch (JSONException w) {
w.printStackTrace()
}
mFruitItemsList.add(fruitItem);
}
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
}
I may not be a pro but I know that I have goofed somewhere in the codes above, else it should have worked.
Now, my question is where did I goof and how do I plug this mistake?
EDIT
I have edited the codes above to reflect the answer that I accepted. It works fine but there is still a problem.
I start Activity B from MainActivity. If I press the back-button in Activity B the data is saved but when I press the up-button, the getData is called again and the data is re-fetched.
Please, is there anyway around this?
You don't seem to have an onSaveInstanceState in your mainactivity. You need something like
#Override
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(KEY_POST_ITEMS,mFruitItemsList) ;
}
In order to retain your data for the activity that is about to be destructed and the one that is being created, you need to override the onSaveInstance callback
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(KEY_POST_ITEMS, (ArrayList)mFruitItemsList);
super.onSaveInstanceState(savedInstanceState);
}
NOTE: always remember to call the superclass.

Refreshing listview to update the data?

I've a listview with some static data. When the refresh activity is done, some data need to be updated in listview. The problem is once the refresh gets completed, the new items are not updated.
MainActivity.class
public class MainActivity extends ActionBarActivity {
SwipeRefreshLayout swipeLayout;
String[] players = {"Dravid","Ganguly","Sachin","Irfan pathan","Balaji","Bhuvi","Praveen"};
ListView listView;
ArrayAdapter<String> adapter = null;
ArrayList al = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
for (int i =0; i<players.length; i++)
{
Bean b = new Bean();
b.setName(players[i]);
al.add(b);
}
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,players);
listView.setAdapter(adapter);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
new updateItems().execute();
}
});
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
class updateItems extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
String[] newitems = {"Ishant sharma","Ramesh power","Kaif"};
// adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,newitems);
for (int j=0;j<newitems.length;j++)
{
Bean bb = new Bean();
bb.setName(newitems[j]);
al.add(bb);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
listView.invalidateViews();
}
});
swipeLayout.setRefreshing(false);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Bean.class
public class Bean {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Where i am making mistake?
This is the adapter that you're setting initially :
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,players);
Inside your doInBackground() method, you update the a1 ArrayList but your players Array on which the adapter depends remains the same hence no changes are reflected in the listview even when you do adapter.notifyDataSetChanged().
Secondly, the onPostExecute method runs on the ui thread so you do not need to do that explicitly.

List view doesn't show text

I need to get text from a website which is done in a new thread. Then i need to put that text in a list view.
The problem is that i cant set up array adapter for list view until text is put in the lists used in that adapter. Lists are filled in that thread used for connecting to website.
I tried to solve that by setting up adapter in new thread run by first thread. Program starts without errors, but nothing shows up in list view.
I am using List view code from this site http://www.vogella.com/articles/AndroidListView/article.html
Im a newbie in java and android so i hope you understand what im trying to do :)
Heres the code
package com.example.studentservis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.R.string;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class MainActivity extends Activity {
String s;
List<String> headersList = new ArrayList<String>();
List<String> contentList = new ArrayList<String>();
ListView listview;
StableArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listView1);
threadStart();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void adapterInit()
{
adapter = new StableArrayAdapter(this, android.R.layout.simple_list_item_1, headersList);
listview.setAdapter(adapter);
}
private class StableArrayAdapter extends ArrayAdapter<String>{
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public StableArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
}
public void threadStart()
{
//txtView.setText(stringHandler.getString());
new Thread(new Runnable() { // thread
public void run(){
try
{
webRequest();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
adapterInit();
}
};
}
}).start();
}
public void webRequest() throws Exception{
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
Elements headersNode = jobNode.select("h1");
Elements contentNode = jobNode.select("content");
for(int i = 0; i < headersNode.size(); i++){
headersList.add(headersNode.get(i).text());
}
for(int i = 0; i < contentNode.size(); i++){
contentList.add(contentNode.get(i).text());
}
}
}
Hope this may work for you, here i used Asynchronous Task instead of thread
public class MainActivity extends Activity {
String s;
List<String> headersList = new ArrayList<String>();
List<String> contentList = new ArrayList<String>();
ListView listview;
StableArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listView1);
// threadStart();
// Here i implemented Asynchronous Task instead of Thread
new SampleAsyncTask().execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class SampleAsyncTask extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
MainActivity.this);
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
webRequest();
adapter = new StableArrayAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, headersList);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result) {
// Here if you wish to do future process for ex. move to another
// activity do here
listview.setAdapter(adapter);
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
private class StableArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public StableArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
}
public void webRequest() throws Exception {
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
Elements headersNode = jobNode.select("h1");
Elements contentNode = jobNode.select("content");
for (int i = 0; i < headersNode.size(); i++) {
headersList.add(headersNode.get(i).text());
}
for (int i = 0; i < contentNode.size(); i++) {
contentList.add(contentNode.get(i).text());
}
}
}
At first I propose you to read this guide, especially about Using AsyncTask instead raw Thread.
At second, as I understand, you want to invoke adapterInit from UI thread?
So, you can try this:
runOnUiThread( // <-- method from Activity
new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
adapterInit();
}
}
);
Maybe the problem is that you are not calling the method notifyDataSetChanged() on the adapter to force it to update his informations, it's like notifying the adapter that the underlaying data were updated and that it needs to refresh the associated listview.
You should call it after you fetch the data from the website.
You can use Handler.
In the webRequest thread,When webRequest() finished,you use Handler to notice the main thread to adapterInit().Not use another thread in the webRequest thread.
A simple example.
#Override
public void onClick(DialogInterface dialog,
int which) {
setControlsEnable(false);
new Thread() {
public void run() {
WebserviceMethod wb = new WebserviceMethod();
if (wb.DeleteEmployee(
VerificationUtils
.GetInstance()
.CreateToken(),
personId) == 1) {
Message msg = new Message();
msg.obj = SwitchActivityValue.SWITCH_DELETEPERSON_OK;
mHandler.sendMessage(msg);
}
}.start();
}
#Override
public void handleMessage(Message msg){
super.handleMessage(msg);
SwitchActivityValue value = (SwitchActivityValue)msg.obj;
switch (value) {
case SWITCH_DELETEPERSON_OK:
ManageUtils.EmployeeListDataForAdmin.personInfos.clear();
ManageUtils.EmployeeListDataForAdmin.currentPage = 0;
mActivity.switchActivity(mValue);
break;
case SWITCH_DELETEPERSON_FAILED:
break;
default:
break;
}
mActivity.showMessage(value);
}
Such as the example,you can bind the data in the Handler.When the thread finished,it use hanlder to sendmessage to notice handleMessage handle others.

Android ListView won't populate

I'm trying to populate my ListView with values from a string array. There are values in the string array, as I've checked to make sure. I'm using code that, from what I've seen from previous searches, is correct. I'm running the app through an Android emulator and have tried creating a new emulator, cleaning the project, and restarting Eclipse. But still when the app starts up there is no data in the list.
I'm using the Galaxy Nexus emulator running Android 4.2.
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView redditView = (ListView) findViewById(R.id.redditView);
String[] redditList = readRedditFeed();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1, redditList);
redditView.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public String[] readRedditFeed()
{
return output;
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="#+id/redditView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
You are parsing data in main thread it may give ANR.
Use either Thread and handler or AsyncTask.
After getting parsed result from thread use handler to set adapter in your list
OR
use AsyncTask doInbackground() method to receiving and parsing data and onPostExecute()
set adapter in your list.
just use an asyncTask to do the background work without blocking the UI.
private LoadingStuffTask task;
private String [] redditList;
private ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView redditView = (ListView) findViewById(R.id.redditView);
task = new LoadingStuffTask();
task.execute("Process started!");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private class LoadingStuffTask extends
AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
redditList=readRedditFeed()
}
#Override
protected void onProgressUpdate(
String... values) {
}
#Override
protected void onPostExecute(String result) {
pdia.dismiss();
adapter = new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1, redditList);
redditView.setAdapter(adapter);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pdia = new ProgressDialog(classificaA.this);
pdia.setMessage("Doing background..");
pdia.show();
}
}
public String[] readRedditFeed()
{
ArrayList<String> redditList = new ArrayList<String>();
try
{
URL url = new URL("http://www.reddit.com/.json");
InputStream in = url.openStream();
DataInputStream din = new DataInputStream(new BufferedInputStream(in));
String line = "";
String lines = "";
while((line = din.readLine()) != null)
lines += line;
JSONObject json = (JSONObject) new JSONTokener(lines).nextValue();
json = (JSONObject) json.getJSONObject("data");
JSONArray jsonArr = (JSONArray) json.getJSONArray("children");
for(int i = 0; i < 5; i++)
{
json = jsonArr.getJSONObject(i);
json = (JSONObject) json.getJSONObject("data");
redditList.add(json.get("title").toString().replaceAll("\"", ""));
}
}
catch (Exception e)
{}
String[] output = new String[redditList.size()];
redditList.toArray(output);
return output;
}
}

Categories

Resources