0

When I press a button, its supposed to retrieve data from a webpage and display it according to my layouts. It does this fine, but only if I click back, go back to my main activity(home activity) and press the button again.

It takes forever to load the first time I press the button and sometimes doesn't work. But the second time is instant load[works fine].

Here's the code - Three classes - HomeActivity.java, News.Java and MyNewsHandler.java

public class HomeActivity extends Activity
{
String username = " ";
Button alog;
Button news;
Button forumTime;
EditText usernameEntry;
SharedPreferences preferences;
ImageView image;
TextView usernametv;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    forumTime = (Button)findViewById(R.id.timeButton);
    news = (Button) findViewById(R.id.newsButton); // <--- Heres the problem
    alog = (Button) findViewById(R.id.alogButton);
    usernameEntry = (EditText) findViewById(R.id.username);


    //For news button
    OnClickListener newsListener = new OnClickListener()
    {
        public void onClick(View v)
        {
            Intent intent = new Intent(HomeActivity.this, News.class);
            startActivity(intent);
        }
    };

    //Attaching listeners
    //forumTime.setOnClickListener(timeListener);
    //alog.setOnClickListener(alogListener);
    news.setOnClickListener(newsListener);
}

public void display(String string)
{
    Toast.makeText(getBaseContext(), string, 300000).show();
}

}

public class MyNewsHandler extends DefaultHandler
{
private Boolean inTitle = false;
private Boolean inDescription = false;
private Boolean inItem = false;
private Boolean inCategory = false;
static public ArrayList<String> title = new ArrayList<String>(),
    description = new ArrayList<String>(), category = new ArrayList<String>();
private StringBuilder buff = null;
// All methods auto called in this order - start, characters, end
/*
 * Called when an xml tag starts
 * imgView.setImageResource(R.drawable.newImage);
 */
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) 
{
    if (inItem) 
    {
        if (localName.equals("title")) 
        {
            inTitle = true;
            buff = new StringBuilder();
        }
        if (localName.equals("description")) 
        {
            inDescription = true;
            buff = new StringBuilder();
        }
        if (localName.equals("category")) 
        {
            inCategory = true;
            buff = new StringBuilder();
        }

    }
    if (localName.equals("item")) 
    {
        inItem = true;
    }
}
/*
 * Called when an xml tag ends
 */
@Override
public void endElement(String uri, String localName, String qName)throws SAXException 
{
    if (!inTitle && !inDescription && !inCategory) 
    {
        inItem = false;
    } 
    else 
    {
        if (inTitle) 
        {
            String check = buff.toString().trim();
            title.add(check);
            inTitle = false;
            buff = null;
        }
        if (inDescription) 
        {
            String check2 = buff.toString().trim();
            String array [];
            int index = 0;
            if (check2.contains("/>"))
            {
                array = check2.split("/>");
                index = check2.indexOf("10;");
                description.add(array[array.length - 1].trim());
            }

            else description.add(check2);
            //description.add(array[1]);
            inDescription = false;
            buff = null;
        }
        if(inCategory)
        {
            String check = buff.toString().trim();
            category.add(check);
            inCategory = false;
            buff = null;
        }
    }
}
/*
 * Called to get tag characters
 */
@Override
public void characters(char ch[], int start, int length) 
{
    if (buff != null) 
    {
        for (int i = start; i < start + length; i++) 
        {
            buff.append(ch[i]);
        }
    }
}

}

public class News extends ListActivity
{
String url;
TextView text1;
TextView text2;
static ImageView img;
// newsList contains the list items 
static ArrayList<HashMap<String, Object>> newsList = new ArrayList<HashMap<String, Object>>();
// to store drawable id's
static HashMap<String, Integer> images = new HashMap<String, Integer>();
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    //Load xml containing image view and a linear layout with 2 textviews
    setContentView(R.layout.aloglistview); 

    img = (ImageView)findViewById(R.id.imageView2);
    text1 = (TextView) findViewById(R.id.text1);
    text2 = (TextView) findViewById(R.id.text2);

    // url we are retrieving from
    url = "http://services.runescape.com/m=news/latest_news.rss";

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(url);
    String result = ""; // result of http Post
    try
    {
        // Execute HTTP get Request
        HttpResponse response = httpclient.execute(httpget);

        // Extract the page content returned from the response
        BufferedReader in = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");
        while ((line = in.readLine()) != null)
        {
            sb.append(line + NL);
        }
        in.close();
        result = sb.toString(); // resulting content of the page
    } catch (ClientProtocolException e)
    {
        Log.d("ERROR", "ClientProtocolException=" + e);
        System.err.println("ClientProtocolException=" + e);
    } catch (IOException e)
    {
        Log.d("ERROR", "IOException=" + e);
        System.err.println("IOException=" + e);
    }
    try
    {
        //Parse the resulting page 
        Xml.parse(result, new MyNewsHandler());
    } catch (SAXException e)
    {
        e.printStackTrace();
    } catch (Exception e)
    {
        e.printStackTrace();
    }
    //needs to match formulate list thing
    SimpleAdapter adapter = new SimpleAdapter(this, newsList,
            R.layout.newsitem, new String[] { "Title", "Description", "Image"},
            new int[] { R.id.textnews1, R.id.textnews2, R.id.imageView2});

    populateList(); //Add all items to the newslist 
    setListAdapter(adapter);
}
public  void populateList()
{
    //Method to add to images hashmap 
    initMap();
    //reset each time the list is populated
    newsList = new ArrayList<HashMap<String, Object>>();
    //Display 10 items
    for (int i = 0; i < 11; i++)
    {
        HashMap<String, Object> temp = new HashMap<String, Object>();
        String title = MyNewsHandler.title.get(i);
        String category = MyNewsHandler.category.get(i);
        //default drawable
        int drawable = R.drawable.item;
        //Match title text to hash keys to set correct image
        for (Map.Entry<String, Integer> entry : images.entrySet()) 
        {
            String key = entry.getKey();
            Object value = entry.getValue();
            if(category.contains(entry.getKey()))
            {
                drawable = entry.getValue();
                break;
            }
            else drawable = R.drawable.item;
        }
        temp.put("Title", title);
        temp.put("Description", " " + MyNewsHandler.description.get(i));
        temp.put("Image",drawable);
        newsList.add(temp);
    }
}
public void display(String string)
{
    Toast.makeText(getBaseContext(), string, 1000202).show();
}
public void initMap()
{
    images.put("Behind the Scenes News",R.drawable.behindthescenes);
    images.put("Customer Support News",R.drawable.customerservice);
    images.put("Game Update News",R.drawable.gameupdate);
    images.put("Website News",R.drawable.devblog);
    images.put("Technical News",R.drawable.technicalnews);
}

}

Sorry the code is so long.. The problem is it works (ha..), but it doesn't load instantly when i want it to the first time.

It does this: Start app> hit news button> "doesnt load, blank screen"

but it works when I do this: start app> hit news button> hit back> hit news button> "instantly loads"

I followed a suggestion where I pre-parsed before hitting the button, also did another attempt where I got rid of images altogether(thinking that might be the delay). No difference. Still the same behaviour.

Any suggestion is appreciated!

Geo
  • 12,666
  • 4
  • 40
  • 55
shecodesthings
  • 1,218
  • 2
  • 15
  • 33
  • I think your problem lies in step 2. Do you hit the website every time the news activity loads? Are you doing the HTTP connection in a separate thread? Can you show the code for connecting and retrieving the response? – Steve Blackwell May 03 '12 at 01:42
  • hard to say what might be the problem without seeing the code... I know you think it's standard stuff, but since your explanation doesn't have any obvious errors in it, we'd need to look at what you're actually doing to offer useful advice. – Yevgeny Simkin May 03 '12 at 01:45
  • Added in the code for you guys. – shecodesthings May 03 '12 at 21:26
  • @Geo please take a look at the second point in [the post you referenced](http://meta.stackexchange.com/questions/135985/) *If you retag some posts manually, don't just change that one tag: take the time to do do any other warranted improvement (other tags, spelling, formatting, etc.). If you see a question that should be closed, vote or flag it.* The third is also valid. Make sure there's a wiki as well. Also read [In Defense of Editing](http://blog.stackoverflow.com/2009/04/in-defense-of-editing/) which also talks about the importance of substantive editing. – Conrad Frix Dec 28 '12 at 20:38
  • Good point, thank you @ConradFrix ! I just created a [wiki](http://stackoverflow.com/tags/load-time/info) for the `load-time` tag. It has to be approved. – Geo Dec 28 '12 at 20:54

2 Answers2

1

Tree points:

  1. Use AsyncTask for anything not directly related to UI
  2. Cache everything. Once you've got XML from web-site, save it somewhere and next time load from the file before starting download.
  3. Preload. Don't wait for the user to click the button. As soon as your application is started, fire up AsyncTask (see p.1) to perform background download and XML parsing. By the time the user pushes the button, the results will be ready.
lenik
  • 23,228
  • 4
  • 34
  • 43
  • Hi I did try preloading the xml, before hte user hits the button. But the behaviour did not change. – shecodesthings May 03 '12 at 21:26
  • then you might have a problem with DNS settings, first request timeouts or takes a long time because there's no data about the location of the server you're trying to download the data from. and the second time it's already in the cache, so it works almost instantly. you may try to use numeric address (123.234.123.234) instead of domain name in your XML request and see what happens. – lenik May 04 '12 at 05:46
  • Sorry it took me so long to accept this...!! I got this working ages ago! – shecodesthings Jun 04 '13 at 15:12
1

Everything lenik said.

My solution was only slightly different. I did something like this:

  1. On (button press or other triggering event) issue an Intent that kicks off an IntentService (instead of AsyncTask). Why? Its syntax is simpler, and I want to call it from several places.
  2. Start showing results immediately and populate it with results as they trickle in. I do this the easy way exposing all my data through a ContentProvider and running the ListFragment off that.
Sparky
  • 8,437
  • 1
  • 29
  • 41
  • Hey guys thanks for all the help! I did try almost everything everyone sugggested, but i'd always get stuck somewhere else. I found this great site today - > http://www.ibm.com/developerworks/xml/tutorials/x-androidrss/ and it really fixed the problem, all I have to do now is figure out how to add images to the actual ListView... – shecodesthings May 06 '12 at 03:21