Question

So, I've built an Ok RSS reader for a new sports app I'll be releasing soon. It will read feeds from various sports sites and display them. The problem I have is that the feeds are loading immediately on the start of an activity which requires an internet connection.

If an internet connection goes down or there is latency, the app will sometimes hang and/or force close on me. I need something pause the screen until the feed contents have been pulled from the various XML feeds.

Many news apps and other RSS readers do this when you click on a new news category. You'll get an animated "updating" or "loading" dialogue. Here is my current code.

public class MyActivity extends ListActivity implements OnClickListener {

    Button btn1;
    Button btn2;
    Button btn3;
    Button btn4;

    WebView webview;

    TextView feedTitle;
    TextView feedDescribtion;
    TextView feedPubdate;
    TextView feedLink;

private RSSFeed myRssFeed = null;

public class MyCustomAdapter extends ArrayAdapter<RSSItem> {

 public MyCustomAdapter(Context context, int textViewResourceId,
   List<RSSItem> list) {
  super(context, textViewResourceId, list);
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  // TODO Auto-generated method stub
  //return super.getView(position, convertView, parent);

  View row = convertView;

  if(row==null){
   LayoutInflater inflater=getLayoutInflater();
   row=inflater.inflate(R.layout.row, parent, false);
  }

  TextView listTitle=(TextView)row.findViewById(R.id.listtitle);
  listTitle.setText(myRssFeed.getList().get(position).getTitle());
  TextView listTitle2=(TextView)row.findViewById(R.id.listtitle2);
  listTitle2.setText(myRssFeed.getTitle());
  TextView listPubdate=(TextView)row.findViewById(R.id.listpubdate);
  String str = (myRssFeed.getList().get(position).getPubdate());


  SimpleDateFormat inputFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); //please notice the    capital M
  SimpleDateFormat outputFormatter = new SimpleDateFormat("MM/dd/yyyy");

  try {
      Date date = inputFormatter.parse(str);
      String text = outputFormatter.format(date);
      listPubdate.setText(text);
  } catch (ParseException e ) {
      e.printStackTrace();
  }


  return row;
 }
}

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

      btn1 = (Button) findViewById(R.id.hawknation_button);
      btn1.setOnClickListener(this);

      btn2 = (Button) findViewById(R.id.hawkcentral_button);
      btn2 .setOnClickListener(this);

      btn3 = (Button) findViewById(R.id.hawkeyesports_button);
      btn3 .setOnClickListener(this);

      espn = (Button) findViewById(R.id.espn_button);

      feedTitle = (TextView)findViewById(R.id.feedtitle);
      feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
      feedPubdate = (TextView)findViewById(R.id.feedpubDate);
      feedLink = (TextView)findViewById(R.id.feedlink);

           readRss();
       }

       private void readRss(){

      feedTitle.setText("--- wait ---");
      feedDescribtion.setText("");
      feedPubdate.setText("");
      feedLink.setText("");
      setListAdapter(null);

      Toast.makeText(this, "Reading RSS, Please wait.", Toast.LENGTH_LONG).show();


       try {
          URL rssUrl = new URL("http://www.sports.com/feed");
          SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
          SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
          XMLReader myXMLReader = mySAXParser.getXMLReader();
          RSSHandler myRSSHandler = new RSSHandler();
          myXMLReader.setContentHandler(myRSSHandler);
          InputSource myInputSource = new InputSource(rssUrl.openStream());
          myXMLReader.parse(myInputSource);

          myRssFeed = myRSSHandler.getFeed();

         } catch (MalformedURLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         } catch (ParserConfigurationException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         } catch (SAXException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }

         if (myRssFeed!=null)
         {
          TextView feedTitle = (TextView)findViewById(R.id.feedtitle);
          TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
          TextView feedPubdate = (TextView)findViewById(R.id.feedpubDate);
          TextView feedLink = (TextView)findViewById(R.id.feedlink);
          feedTitle.setText(myRssFeed.getTitle());
          feedDescribtion.setText(myRssFeed.getDescription());
          feedPubdate.setText(myRssFeed.getPubdate());
          feedLink.setText(myRssFeed.getLink());

          MyCustomAdapter adapter =
           new MyCustomAdapter(this, R.layout.row, myRssFeed.getList());
          setListAdapter(adapter);
         }
         }       


@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
 // TODO Auto-generated method stub
 Intent intent = new Intent(this,HawkCentralDetails.class);
 Bundle bundle = new Bundle();
 bundle.putString("keyTitle", myRssFeed.getItem(position).getTitle());
 bundle.putString("keyDescription", myRssFeed.getItem(position).getDescription());
 bundle.putString("keyLink", myRssFeed.getItem(position).getLink());
 bundle.putString("keyPubdate", myRssFeed.getItem(position).getPubdate());
 intent.putExtras(bundle);
      startActivity(intent);
}
Was it helpful?

Solution

You should try using the AsyncTask it will help follow the below link

http://developer.android.com/reference/android/os/AsyncTask.html

With AsyncTask you get to load the data in background and is displayed when loaded till the time you can display a ProgressDialog

OTHER TIPS

You need to call readRSS() in separate thread as oncreate comes with restriction on time it takes. You can use a thread to fetch rss and update the UI by putting it in UI thread or use async task

refer http://developer.android.com/resources/articles/painless-threading.html

Either you can use asynctask or use the following code which uses message queue to make sure that the content is shown to the user only when its loaded fully from the web request and since its running in a seperate thread the GUI is not paused as well: InputSource myInputSource;

public void sampleFunction()
    {


        progressDialog = ProgressDialog.show(this, "", "Getting data...");
        new Thread() {
            public void run() {
                try {
                    //do the web request to get the feeds
                   myInputSource = new InputSource(rssUrl.openStream());
                }catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                messageHandler.sendEmptyMessage(0);
                //              messageHandler.sendEmptyMessage(0);
            }
        }.start();
    }
}


//inside the handler set the string array retrieved from the WS in sampleFunction to the adapter
private Handler messageHandler = new Handler() {

        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //here write the code to parse the value stored in myInputSource 

        }
    };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top