In the code below, the list view does not show the text getting from RSS Feed:
public class MainActivity extends ListActivity {
ArrayList<String> values = new ArrayList<>();
ArrayList<String> tags = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
URL url = new URL("http://appline.ir/index.php/android.feed?limitstart=");
new Connect(url).execute();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class Connect extends AsyncTask <Void, String, String>
{
URL url;
ProgressDialog diao;
Connect(URL url)
{
this.url = url;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
diao.hide();
setListAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, values));
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
diao = new ProgressDialog(MainActivity.this);
diao.setMessage("connecting...");
diao.setIndeterminate(true);
diao.show();
}
#Override
protected String doInBackground(Void... params)
{
try
{
XmlPullParserFactory parser =XmlPullParserFactory.newInstance();
XmlPullParser xml = parser.newPullParser();
URL url = new URL("http://appline.ir/index.php/android.feed?limitstart=");
XmlParser p = new XmlParser(url);
tags = p.parse();
InputStream input = url.openStream();
xml.setInput(input,null);
int event;
String text = null;
try {
event = xml.getEventType();
while (event != XmlPullParser.END_DOCUMENT)
{
String name=xml.getName();
switch (event)
{
case XmlPullParser.START_TAG:
break;
case XmlPullParser.TEXT:
text = xml.getText();
break;
case XmlPullParser.END_TAG:
if(name.equals("title")){
values.add(text);
}
else if(name.equals("link")){
// link = text;
}
else if(name.equals("description")){
// description = text;
}
else{
}
break;
}
event = xml.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
catch(Exception e)
{
}
return null;
}
}
}
but when I put Xml parsing part into the MainActivity (using StrictMode), the list shows the text properly.
I cannot find the problem. How can this be fixed?
You must call notifyDataSetChanged() on your Adapter and you must call it in your UI main thread
Try assigning the adapter object to a variable and call notifyDataSetChanged()
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyActivity.this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
adapter.notifyDataSetChanged();
Related
I'm having a hard time figuring out how to implement the new MyAsyncTask().execute("") that I've searched because I have separate classes that extends Asynctask. I wanted to call the class everytime i click the button. Hope you guys can help me figure this out.
Here is my MainActivity
public class MainActivity extends AppCompatActivity {
String url = "http://192.168.254.103/dbtest/categories.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.start);
final ListView lv = (ListView) findViewById(R.id.lv);
final Downloader d = new Downloader(this,url,lv);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.execute();
}
});
}
}
Here is my Downloader.java
public class Downloader extends AsyncTask<Void,Integer, String> {
Context c;
String address;
ListView lv;
ProgressDialog pd;
public Downloader(Context c, String address, ListView lv) {
this.c = c;
this.address = address;
this.lv = lv;
}
//BEFORE JOB STARTS
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Fetch Data");
pd.setMessage("Please Wait");
pd.show();
}
#Override
protected String doInBackground(Void... params) {
String data = downloadData();
return data;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pd.dismiss();
if(s != null){
Parser p =new Parser(c,s,lv);
p.execute();
}else
{
Toast.makeText(c,"Unable to download data",Toast.LENGTH_SHORT).show();
}
}
private String downloadData(){
//connect and get a stream
InputStream is = null;
String line = null;
try{
URL url = new URL(address);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(con.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
if(br != null){
while((line = br.readLine()) != null)
{
sb.append(line+"\n");
}
}
else
{
return null;
}
return sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
and my Parser.java
public class Parser extends AsyncTask<Void,Integer,Integer> {
Context c;
ListView lv;
String data;
ArrayList<String> categories = new ArrayList<>();
ProgressDialog pd;
public Parser(Context c, String data, ListView lv) {
this.c = c;
this.data = data;
this.lv = lv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parser");
pd.setMessage("Please Wait");
pd.show();
}
#Override
protected Integer doInBackground(Void... params) {
return this.parse();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if(integer == 1)
{
//ADAPTER
ArrayAdapter<String> adapter = new ArrayAdapter<String>(c, android.R.layout.simple_list_item_1, categories);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}else
{
Toast.makeText(c,"Unable to Parse",Toast.LENGTH_SHORT).show();
}
pd.dismiss();
}
//PARSE RECEIVED DATA
private int parse(){
try
{
//ADD TGAT DATA TO JSON ARRAY FIRST
JSONArray ja = new JSONArray(data);
//CREATE JO OBJECT TO HOLD A SINGLE ITEM
JSONObject jo = null;
categories.clear();
//LOOP THROUGH ARRAY
for(int i =0 ; i<ja.length();i++)
{
jo = ja.getJSONObject(i);
//RETRIEVE NAME
String name=jo.getString("cat_name");
//ADD TO ARRAY LIST
categories.add(name);
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}
I have problem with notifyDataSetChanged,i read some another post but can't help me and i have problem yet, i call that after my listview setadapter but mylist hasn't any change! this is my code, please help me, Thanks
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
// this will post our text data
protected void onPreExecute() {
super.onPreExecute();
// do stuff before posting data
}
#Override
protected String doInBackground(String... strings) {
try {
postTextandGetRespons("http://demo.codeofaninja.com/tutorials/json-example-with-php/index.php");
JSONObject JsonOb = new JSONObject(responseString);
JSONArray messages = JsonOb.getJSONArray("Users");
for ( int i=0; i<= f;i++){
JSONObject c = messages.getJSONObject(i);
firstname = c.getString("firstname");
lastname = c.getString("lastname");
username = c.getString("username");
items.add(new item(firstname,lastname,username));
}
adapter.notifyDataSetChanged();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String responseStr) {
if ( setAdapter == true) {
lv = (ListView) findViewById(R.id.listView_asabani);
adapter = new adapter_common(getBaseContext(), items);
lv.setAdapter(adapter);
setAdapter = false;
}
}
}
Move adapter.notifyDataSetChanged(); to onPostExecute() that's where UI code should run.
my app needs to download a rss file in xml. i parse the data but i don't able to insert them into listview.
my code is.
public class MainActivity extends Activity {
ProgressDialog progress =null;
private final static String ADDRESS ="http://www.repubblica.it/rss/sport/rss2.0.xml";
private ListView lista =null ;
private List<ArticleInfo> list = null;
private ArrayAdapter<ArticleInfo> adapter = null ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lista= (ListView)findViewById(R.id.listView);
//adapter =new ArrayAdapter<ArticleInfo>(this,android.R.layout.simple_list_item_1,list);
//lista.setAdapter(adapter);
progress = new ProgressDialog(this);
progress.setMax(100);
progress.setMessage("Attendi qualche istante");
}
public void start(View v){
new BackgroundTask().execute();
}
private class BackgroundTask extends AsyncTask<String,Integer,String> {
#Override
protected String doInBackground(String... params) {
URL url = null;
try {
url = new URL(ADDRESS);
} catch (MalformedURLException e) {
return null;
}
StringBuffer buffer=null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String tmp = null;
buffer = new StringBuffer();
while((tmp=reader.readLine())!= null){
buffer.append(tmp);
}
} catch (IOException e) {
return null;
}
list = RssParser.parseXML(buffer.toString());
return buffer.toString();
}
#Override
protected void onPreExecute(){
progress.setProgress(0);
progress.show();
}
#Override
protected void onProgressUpdate(Integer ... values){
super.onProgressUpdate(values);
progress.setProgress(values[0]);
}
#Override
protected void onPostExecute(String res){
super.onPostExecute(res);
progress.dismiss();
if (res!=null){
// TextView text = (TextView)findViewById(R.id.text);
//text.setText(res);
adapter =new ArrayAdapter<ArticleInfo>(this,android.R.layout.simple_list_item_1,res);
lista.setAdapter(adapter); **THIS IS MY ERROR**
}
}
}
}
this is my parser class
public class RssParser {
public static List<ArticleInfo> parseXML(String rss){
List<ArticleInfo> res =new ArrayList<>();
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder =null;
try {
builder=factory.newDocumentBuilder();
} catch (ParserConfigurationException e) { }
try {
Document doc = builder.parse(new InputSource(new StringReader(rss)));
doc.getDocumentElement().normalize();// aggiungo getDocumentElement()
NodeList list = doc.getElementsByTagName("item");
for(int i=0;i<list.getLength();i++){
Node n=list.item(i);
if(n.getNodeType()==Node.ELEMENT_NODE){
Element e= (Element) n;
String title = e.getElementsByTagName("title").item(0).getTextContent();
String url = e.getElementsByTagName("link").item(0).getTextContent();
res.add(new ArticleInfo(title,url));
}
}
} catch (SAXException e) {
} catch (IOException e) {
}
return res;
}
the framework gives me an error in the last row of main activity where i try to crate the adapter
Could you give me an hand ?
Thanks in advance
The issue is due of this line
adapter =new ArrayAdapter<ArticleInfo>(this,android.R.layout.simple_list_item_1,res);
your ArrayAdapter is expecting a Collection of ArticleInfo, but you are passing res which is one single String. Change your AsyncTask in order to make it return list instead of buffer.toString(), E.g.
private class BackgroundTask extends AsyncTask<String,Integer,List<ArticleInfo>>
and doInBackground returns list instead of buffer.toString()
ok i used the context and the error desappear . when i launch the emulator , when the asynctask works, the app goes in crash. the logcat is j
ava.lang.NullPointerException
at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:153)
at artetecapp.ilfattounofficial.MainActivity$BackgroundTask.onPostExecute(MainActivity.java:123)
at artetecapp.ilfattounofficial.MainActivity$BackgroundTask.onPostExecute(MainActivity.java:73)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
I have a list fragment. When I run the app, I see an empty listView.
I don't know what the problem is. Maybe I should use a library?
public class MyEmployeFragment extends ListFragment {
private static final String ATTRIBUTE_ID = "p_id";
private static final String ATTRIBUTE_NAME = "p_name";
private static final String ATTRIBUTE_LAST_NAME = "p_last_name";
ArrayList<spr_item> ret_data;
MyTask task;
SimpleAdapter sAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
task = new MyTask();
task.execute();
return inflater.inflate(R.layout.my_employe, null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ret_data = new ArrayList<spr_item>();
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
ret_data.size());
Map<String, Object> m;
for (int i = 0; i < ret_data.size(); i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_ID, ret_data.get(i).getId());
m.put(ATTRIBUTE_NAME, ret_data.get(i).getName());
m.put(ATTRIBUTE_LAST_NAME, ret_data.get(i).getLastName());
data.add(m);
}
// массив имен атрибутов, из которых будут читаться данные
String[] from = {ATTRIBUTE_ID, ATTRIBUTE_NAME, ATTRIBUTE_LAST_NAME};
// массив ID View-компонентов, в которые будут вставлять данные
int[] to = {R.id.tw_employe_id, R.id.tw_employe_name, R.id.tw_employe_last_name};
// создаем адаптер
sAdapter = new SimpleAdapter(getActivity(), data, R.layout.list_item_employee,
from, to);
// определяем список и присваиваем ему адаптер
ListView lvSimple = (ListView) getView().findViewById(android.R.id.list);
lvSimple.setAdapter(sAdapter);
}
class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
String s = "5ACACEC6-752B-4EFF-AA50-EEBE58A52113";
// String user_guid = myPrefs.getString("guid", "");
HttpActivity _http = new HttpActivity("192.168.10.11", "80");
_http.set_addr_protocol("/WebSite/P/spr/spr.aspx/");
_http.add_param("query", "spr_employee_get");
// _http.add_param("p_guid", user_guid.toString().trim());
_http.add_param("p_guid", s);
_http.send();
List<spr_item> tempList = _http.getArrayParamValue();
for(int i = 0; i < tempList.size(); i++)
ret_data.add(tempList.get(i));
//employer_name = _http.getArrayParamValue("p_name");
//employer_id = _http.getArrayParamValue("p_id");
//employer_last_name = _http.getArrayParamValue("p_last_name");
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
sAdapter.notifyDataSetChanged();
}
}
}
With the above code apart from the Empty list you may have the null pointer exception too if the task is too quick to load. Here onCreate is called first onCreateView next and onActvityCreated next. So it is better to initialise adapter in onCreate set the adapter to listView in onCreateView and set listView listeners in onActvityCreated using getListView() method.
Apart from this if you are using local database to retrieve data you need to use cursorADapter to fetch the data
The adapter's data references (ArrayList, array, etc.), tend to get lost pretty easily. In that case the notfiyDataSetChanged() method will not work. If you are adamant on using this method I suggest you check the references to the adapter's source again. If that is not the case this is the approach I've used in my project. A small warning in advance, the formatting and the closing of brackets is poorly executed, but the approach is still clear enough.
public class MyFragment extends ListFragment {
// For populating the list view.
SomeAdapter adapter;
public MyFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] parameters = {"url for request"};
new GetRequestTask().execute(parameters);
}
// The async task to make the HTTP GET requests.
class GetRequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e("GetRequestTask", "Client protocol exception.");
e.printStackTrace();
} catch (IOException e) {
Log.e("GetRequestTask", "IO exception.");
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Update UI with the new response.
new UpdateUITask().execute(result);
}
}
}
// The async task to update the UI.
class UpdateUITask extends AsyncTask<String, String, ArrayList<Something>>{
#Override
protected ArrayList<Something> doInBackground(String... input) {
ArrayList<Something> someArray = new ArrayList<Something>();
try{
// Do some JSON magic to parse the data.
}
catch(JSONException je){
Log.e("UpdateUITask", "JSON parsing error occured.");
je.printStackTrace();
}
return someArray;
}
#Override
protected void onPostExecute(ArrayList<Something> result) {
super.onPostExecute(result);
Log.i("UpdateUITask", "Updating UI.");
adapter = new SomeAdapter(getActivity(), R.layout.some_list_item, restOfTheParameters);
setListAdapter(adapter);
}
}
}
}
I am working on one android app in which i want to display progress Dialog till loading of gridview completed. But my problem is progress dialog is spin for some intial time. Then it stops spinning.
Here is my code.
public class allsites extends Activity {
private final String url_select = "http://api.stackexchange.com/2.1/sites?filter=!RGB_Y51.*-(YX";
private GridView gview;
private ListViewCustomAdapter adapter;
private ArrayList<Object> itemList = new ArrayList<Object>();
private ItemBean bean;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.allsites);
//GridView gridview = (GridView) findViewById(R.id.gvAllSites);
gview = (GridView) findViewById(R.id.gvallsites);
new task().execute();
}
private class task extends AsyncTask<Void, Void, GZIPInputStream> {
private ProgressDialog progress;
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(allsites.this, "Loading", "Please Wait...");
}
#Override
protected GZIPInputStream doInBackground(Void... params) {
ServerData httpclient = new ServerData();
GZIPInputStream zis = httpclient.GetServerData(url_select);
return zis;
}
#Override
protected void onPostExecute(GZIPInputStream zis) {
ParseJSON(zis);
if(progress!=null && progress.isShowing()==true)
progress.dismiss();
}
}
private void ParseJSON(GZIPInputStream zis)
{
Gson gson = new Gson();
Reader reader = new InputStreamReader(zis);
Sites response = gson.fromJson(reader, Sites.class);
List<Items> items = response.getItems();
for (Items site : items) {
//Toast.makeText(allsites.this, site.getApi_site_parameter().toString(), Toast.LENGTH_SHORT).show();
AddObjectToList(site.getIcon_url(),site.getName());
}
adapter = new ListViewCustomAdapter(this, itemList);
gview.setAdapter(adapter);
}
public void AddObjectToList(String imageURL, String title)
{
bean = new ItemBean();
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageURL).getContent());
bean.setImage(bitmap);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bean.setTitle(title);
itemList.add(bean);
}
}
Please give me suggestion how i can make progress dialog spinning till gridview get loaded.
move ParseJSON function to doInBackground event
#Override
protected Boolean doInBackground(Void... params) {
ServerData httpclient = new ServerData();
GZIPInputStream zis = httpclient.GetServerData(url_select);
ParseJSON(zis);
return true;
}
#Override
protected void onPostExecute(Boolean zis) {
progress.dismiss();
}