Presentation is loading. Please wait.

Presentation is loading. Please wait.

David Sutton MOBILE INTERNET. OUTLINE  This week’s app – an RSS feed reader  Mobile internet considerations  Threads (recap)  RSS feeds  Using AsyncTask.

Similar presentations


Presentation on theme: "David Sutton MOBILE INTERNET. OUTLINE  This week’s app – an RSS feed reader  Mobile internet considerations  Threads (recap)  RSS feeds  Using AsyncTask."— Presentation transcript:

1 David Sutton MOBILE INTERNET

2 OUTLINE  This week’s app – an RSS feed reader  Mobile internet considerations  Threads (recap)  RSS feeds  Using AsyncTask for network operations  The … notation for parameters  Displaying web pages

3 THIS WEEK’S APPLICATION “BEHIND THE HEADLINES” READER  We will create a simple application that connects to the NHS “Behind the Headlines” RSS Feed.  The app will display a list of news items that have been covered by the Behind the Headlines service with links to the NHS web pages on which those news items are analysed.

4 MOBILE INTERNET CONSIDERATIONS  When writing mobile apps that access the internet we need to pay attention to several issues that might be of less importance when writing a desktop application. Specifically:  Limited bandwidth and reliability of connection  Need to maintain responsiveness (our app will get killed by the OS if we don’t!)  Battery life

5 ANDROID NETWORKING REQUIREMENTS  An app that accesses the internet must have the android.permission.INTERNET uses permission.  If you are targetting SDKs lower than Honeycomb then you should not perform networking operations on the main thread because the app will become unresponsive while the operation is performed.  If you are targetting Honeycomb or higher then you cannot perform networking operations on the main thread because a NetworkOnMainThreadException will be thrown.

6 PICKING UP THE THREADS OF THREADS  Recap of material covered in prerequisite module.  If you are performing some complex task, it is often useful to divide it into separate sequences of operations.  An example from real life: Suppose you want to prepare cauliflower cheese. You could divide the preparation into the following sequences of operations. Chop cauliflower Boil for 5 minutes Drain Grate cheese Make white sauce Add cheese to sauce Put cauliflower into ovenproof dish Add sauce Bake until brown on top The preparation of veg and sauce can be done in parallel We can’t boil the cauliflower until after we have chopped it, but it doesn’t matter whether we do it before or after grating the cheese

7 THREADS  A modern desktop OS will allow many processes to run in parallel. For example you can browse the internet while you wait for your email client to download messages.  Many languages, including Java, allow a singleprocess to contain multiple threads which also execute in parallel and act as lightweight processes.

8 THREADS IN ANDROID  When an Android application is launched a single thread, called the “main thread” is created and, by default, all of the application’s code will run in this thread.  However you can create additional threads. In fact if you wish to perform network operations you have to create additional threads.  You can create a thread by instantiating the Java Thread class. However the Android API includes a class AsyncTask that simplifies the creation of threads (we will look at it in more detail later in the lecture).

9 SOME ANDROID INTERNET CLASSES  The standard classes from the java.net package are available, for example java.net.URL can be used to represent URLs  The standard Java SAX and DOM parsers for XML are also available. However the Android SDK also includes an XMLPullParser class which may run more efficiently on a mobile platform.  The SDK also includes a WebView class. This is a subclass of View that can be used to view HTML retrieved from the net, or supplied as a String.  You can also view web pages by using an implicit Intent to start the native web browser.

10 BEHIND THE HEADLINES The NHS “Behind the Headlines” service provides evidence- based analysis of health stories that appear in the media. It is available as an RSS feed.

11 RSS FEEDS  RSS Stands for “Really Simple Syndication”, or “Rich Site Summary” depending on who you wish to believe.  It is a simple means of publishing frequently updated information.  There is a standard XML format for RSS Feeds.

12 RSS FORMAT Index of Lost Things http://www.wherearethey.com/main.html Those we have lost Lost Sock http://www.wheresmysock.org/ Red knee length sock Lost Cat …. Channel element describes the feed and usually contains several items. Each item must have a title, link, and description. There are other, optional, child elements.

13 UI FOR APPLICATION Do exercise 1 TextView to display status ListView to display items retrieved from feed.

14 A CLASS TO REPRESENT ITEMS public class Item { private String title; private String link; public Item(String title, String link) { this.title = title; this.link = link; } public String getTitle(){ return title; } public String getLink() { return link; } public String toString() { return title; } Do exercise 2

15 ADAPTER FOR ITEMS public class BTHActivity extends Activity { private TextView statusTxt; private ListView itemsLst; private ArrayList items = new ArrayList (); private ArrayAdapter itemsAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bth); statusTxt = (TextView) findViewById(R.id.status_txt); itemsLst = (ListView) findViewById(R.id.items_lst); itemsAdapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, items); itemsLst.setAdapter(itemsAdapter); Do exercise 3

16 READING IN THE BACKGROUND  We must not read data from the internet in the main thread.  However we must not update UI components outside of the main thread.  We need to read data from the internet, and then update our UI components, so we have to run operations in different threads, and synchronize them so that we are not trying to update the UI before we have read all the necessary data.  Fortunately the Android SDK’s AsyncTask class allows us to do exactly that. It is designed to be subclassed, and contains some methods that will run in the main thread, and others that will run in a separate thread, with appropriate synchronisation.

17 ASYNCTASK AsyncTask +execute(Params… params) #doInBackground() #onPostExecute(Result result) #onPreExecute() #onProgressUpdate(Progress… p) #publishProgress(Progress… p) Public method that we call in order to perform the task Protected method that is performed in a separate thread. Designed to be overridden Protected method that is performed in the main thread, after doInBackground has completed. Designed to be overridden Other methods documented at http://developer.android.com/reference/android/os/AsyncTask.html

18 INNER CLASSES  We could create a completely separate class that will extend AsyncTask. However it will be more convenient to create an inner class.  An inner class is defined within another class. The differences between inner classes and standard classes are that:  Each object of the inner class is associated with an object of the enclosing class and has access to all of the fields and methods of the enclosing object (even the private ones).  An inner class can be private. public class A { …. private class B { … }

19 UML NOTATION FOR INNER CLASSES public class Out { …. private class In { … } Out In

20 TYPE PARAMETERS FOR ASYNCTASK  The declaration of the AsyncTask in the Android developer reference looks like this AsyncTask The identifiers inside the are formal type parameters. When we subclass AsyncTask we supply corresponding actual type parameters, much as we do when we instantiate an ArrayList. For example private class ReaderTask extends AsyncTask > The declarations of AsyncTask methods make use of the formal parameters. For example Result doInBackground(Params... params) The methods in the subclass will have the types specified by the corresponding actual parameters. For example protected ArrayList doInBackground(URL... params) We will explain what this … means later

21 TYPE PARAMETERS FOR ASYNCTASK  When we subclass AsyncTask we supply three type parameters, as illustrated by the following example private class ReaderTask extends AsyncTask > The parameter supplied to the execute method is an array of whatever type we specify here. In this case it will be an array of URL objects. The doInBackground method returns a result of whatever type we specify here, which is passed as a parameter to the onPostExecute method. The type supplied here is passed as an argument to the publishProgress method. If we don’t want to use it we can make it Void (note capital ‘V’).

22 OUR ASYNCTASK private class ReaderTask extends AsyncTask >{ private String statusMessage; @Override protected ArrayList doInBackground(URL... params) { … } @Override protected void onPostExecute(ArrayList result) { … } We will use this field to store a message to be displayed in the UI text field. Code to read the feed and return a list of Items representing its content. Code that uses the values of the fields to update the UI (runs in main thread),

23 THE … NOTATION The signature of the doInBackground method of the AryncTask class is protected ArrayList doInBackground(URL... params) the … means that the method can be called with a variable number of parameters, so long as they are all of type URL. For example if we were calling it directly then call could be like this doInBackground(url1) or like this doInBackground(url1, url2, url3) We do not call the method directly, but we do call it indirectly when we call the execute method. This also can take a variable number of parameters of type URL (we will in fact pass only one parameter).

24 THE … NOTATION Within the body of the doInBackground method, we treat the params parameter as an array. If we pass only one actual parameter then this is at element 0 of the array. Hence the code that establishes the input stream for the parser will look something like this. We will explain what the XMLPullParserFactory class does later XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); parser = factory.newPullParser(); parser.setInput(params[0].openStream(), null); protected ArrayList doInBackground(URL... params)

25 EXECUTING THE TASK ReaderTask readerTask = new ReaderTask(); try { URL url = new URL( "http://feeds.feedburner.com/NhsChoicesBehindTheHeadlines?format=xml"); readerTask.execute(url); } catch (MalformedURLException ex){ //this should not happen statusTxt.setText("Bad URL"); } Do exercise 4

26 PARSING XML  The standard Java API provides classes that implement two kinds of parser for XML:  DOM parsers convert an entire XML document into a tree structure.  SAX parsers allow the programmer to write code that responds to events that occur as an XML document is read (an example of an event would be parser encountering a start tag).  The Android SDK also provides a simple, event based, parser class XMLPullParser.  An XMLPullParser reads an XML document and interprets what it reads, as a set of events. The first event is the “start document” event. Subsequent events may be “start tag” events (i.e. the parser has just encountered the start tag for an element), “end tag” events, “text” events, and so on.

27 SOME XMLPULLPARSER METHODS voidsetInput(Reader in)Sets the input stream for the parser int getEventType ()Returns an integer describing the type of the current event. Possible return values are identified by constants, START_TAG, START_DOCUMENT, END_TAG, etc. int next()Move on to the next event. String getName ()Get the name of the current tag (if the current event type is START_TAG or END_TAG). String getText ()Get the text content of the current event. Full details at http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html

28 OBTAINING AN XMLPULLPARSER  The XMLPullParser class is abstract, so we cannot instantiate it directly using the keyword ‘new’.  Instead we make use of the XMLPullParser factory class. The constructor for this class is protected, so we can’t use ‘new’ to instantiate it either. We have to use its static newInstance method.  Here is how we create a parser: XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XMLPullParser parser = factory.newPullParser();

29 A USEFUL METHOD /** * Determine whether a parser is currently parsing the start of a given element * @param parser The XMLPullParser being use * @param name Name of the tag * @return true if the parser is currently at the named tag, false otherwise * @throws XmlPullParserException */ private boolean isStartTag(XmlPullParser parser, String name) throws XmlPullParserException { return (parser.getEventType() == XmlPullParser.START_TAG) && parser.getName().equalsIgnoreCase(name); } We can define a similar methods isEndTag, isEndDocument, etc..

30 ANOTHER USEFUL METHOD /* * Get the textual contact of a named element * @pre The element has textual content * @param parser The XMLPullParser being used * @param name Name of the element * @return Textual content of the element * @throws XmlPullParserException * @throws IOException */ private String getTagText(XmlPullParser parser, String name) throws XmlPullParserException, IOException { String result = null; while (!isEndTag(parser, name) && !isEndDoc(parser)) { if (parser.getEventType() == XmlPullParser.TEXT) { result = parser.getText(); } parser.next(); } return result; }

31 GETTING ITEM DATA FROM FEED In order to read the data we need to create an Item from the RSS feed. We need to look for “item” tags, then read the “title” and “link” child elements, ignoring other child elements Does housework count towards exercise targets? http://www.nhs.uk/news/2013/10October/Pages/Does-housework-count-towards-exercise-targets.aspx …

32 GETTING ITEM DATA FROM FEED private Item getItem(XmlPullParser parser) throws XmlPullParserException, IOException { String title = "???"; String link = null; while (!isEndTag(parser, "item") && !isEndDoc(parser)) { if (isStartTag(parser, "title")) { title = getTagText(parser, "title"); } else if (isStartTag(parser, "link")) { link = getTagText(parser, "link"); } parser.next(); } if (isEndTag(parser, "item")) { return new Item(title, link); } else { return null; }

33 UPDATING THE UI @Override protected void onPostExecute(ArrayList result) { statusTxt.setText(statusMessage); items.clear(); items.addAll(result); itemsAdapter.notifyDataSetChanged(); } This is the result returned by the doInBackground method

34 WHAT YOU SHOULD SEE Do exercise 5

35 DISPLAYING WEB PAGES  Each Item in the list we have populated contains a link to a web page. We could display that web page in two different ways:  Launch the native browser by starting an activity whose action string is Intent.ACTION_VIEW and whose data attribute is the web link.  Write a new Activity whose UI includes a WebView  The first of those two methods is easier, so we’ll go with that one.

36 DISPLAYING WEB PAGES protected void onCreate(Bundle savedInstanceState) { … itemsLst.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { launchBrowser(position); } }); … private void launchBrowser(int position) { Item item = items.get(position); String link = item.getLink(); Uri uri = Uri.parse(link); Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uri); startActivity(launchBrowser); } Do exercise 6

37 SUMMARY  Network operations must not be performed in the main thread.  The AsyncTask class makes it easy to perform operations in a separate thread.  The XMLPullParser class provides a simple, event based, XML parser  We can display web pages by using an implicit intent to launch the native browser, or by using the WebView class.


Download ppt "David Sutton MOBILE INTERNET. OUTLINE  This week’s app – an RSS feed reader  Mobile internet considerations  Threads (recap)  RSS feeds  Using AsyncTask."

Similar presentations


Ads by Google