{"id":315,"date":"2010-10-31T20:01:00","date_gmt":"2010-10-31T20:01:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/android-full-app-part-4-performing-the-api-request-asynchronously-from-the-main-activity.html"},"modified":"2012-10-21T19:20:05","modified_gmt":"2012-10-21T19:20:05","slug":"android-full-app-part-4-asynchronous","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html","title":{"rendered":"Android Full App, Part 4: Performing the API request asynchronously from the main activity"},"content":{"rendered":"<p>This is the fourth part of the <a href=\"http:\/\/www.javacodegeeks.com\/2010\/10\/android-full-application-tutorial.html\">\u201cAndroid Full Application Tutorial\u201d series<\/a>. The complete application aims to provide an easy way of performing movies\/actors searching over the internet. In the first part of the series (<a href=\"http:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-1-main-activity.html\">\u201cMain Activity UI\u201d<\/a>), we created the Eclipse project and set up a basic interface for the main activity of the application. In the second part (<a href=\"http:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-2-using-http-api.html\">\u201cUsing the HTTP API\u201d<\/a>), we used the Apache HTTP client library in order to consume an external HTTP API and  integrate the API&#8217;s searching capabilities into our application. In the third part (<a href=\"http:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-3-parsing-xml.html\">\u201cParsing the XML response\u201d<\/a>) we saw how to parse the XML response using Android&#8217;s built-in XML parsing capabilities. In this part, we will tie together the HTTP retriever and XML parser services in order to perform the API search request from our application&#8217;s main activity. The request will be executed asynchronously in a background thread in order to avoid blocking the main UI thread.<\/p>\n<p>On mobile applications development, one very important aspect of the application&#8217;s behavior is the smooth execution. The application&#8217;s response to user input should be quick and the whole experience should be smooth and snappy. Application responsiveness is very significant especially for the Android platform and Google has published some <a href=\"http:\/\/developer.android.com\/guide\/practices\/design\/responsiveness.html\">design guidelines<\/a> for that. This is the reason that we will have the application perform the searching operations in the background, meaning that those will execute in a thread other than the main UI thread.<\/p>\n<p>Despite the fact that internet connection rates on mobile devices have been tremendously improved over the last years, it still remains a fact that downloading data from the internet can be a time consuming operation. Thus, we don&#8217;t want to pause the main thread while the HTTP client waits for the data to be downloaded. Also note that stalling the main thread UI for more than five seconds will cause an \u201cApplication Not Responding\u201d (ANR) dialog to kick in and the user will be given the opportunity to kill your application. That is definitely not a feature to have.<\/p>\n<p>For that purpose, we are going to leverage the Android API and use the built in class named <a href=\"http:\/\/developer.android.com\/reference\/android\/os\/AsyncTask.html\">AsyncTask<\/a>. I have explained its usage in a previous post of mine (<a href=\"http:\/\/www.javacodegeeks.com\/2010\/09\/android-reverse-geocoding-yahoo-api.html\">\u201cAndroid Reverse Geocoding with Yahoo API \u2013 PlaceFinder\u201d<\/a>) but in short, this class allows us to properly and easily use the UI thread. From the <a href=\"http:\/\/developer.android.com\/reference\/packages.html\">official documentation page<\/a>: \u201c<a href=\"http:\/\/developer.android.com\/reference\/android\/os\/AsyncTask.html\">AsyncTask <\/a>enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and\/or handlers\u201d.<\/p>\n<p>Before we begin writing the asynchronous code, we will first introduce some service classes which will be responsible for performing the HTTP requests, parsing the XML responses, create the corresponding model objects and returning those to the calling Activity. Those classes will extend the abstract base class named GenericSeeker with the following source code:<\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.android.apps.moviesearchapp.services;\r\n\r\nimport java.net.URLEncoder;\r\nimport java.util.ArrayList;\r\n\r\npublic abstract class GenericSeeker&lt;E&gt; {\r\n    \r\n    protected static final String BASE_URL = \"http:\/\/api.themoviedb.org\/2.1\/\";    \r\n    protected static final String LANGUAGE_PATH = \"en\/\";\r\n    protected static final String XML_FORMAT = \"xml\/\";\r\n    protected static final String API_KEY = \"&lt;YOUR_API_KEY_HERE&gt;\";\r\n    protected static final String SLASH = \"\/\";\r\n    \r\n    protected HttpRetriever httpRetriever = new HttpRetriever();\r\n    protected XmlParser xmlParser = new XmlParser();\r\n    \r\n    public abstract ArrayList&lt;E&gt; find(String query);\r\n    public abstract ArrayList&lt;E&gt; find(String query, int maxResults);\r\n\r\n    public abstract String retrieveSearchMethodPath();\r\n    \r\n    protected String constructSearchUrl(String query) {\r\n        StringBuffer sb = new StringBuffer();\r\n        sb.append(BASE_URL);\r\n        sb.append(retrieveSearchMethodPath());\r\n        sb.append(LANGUAGE_PATH);\r\n        sb.append(XML_FORMAT);\r\n        sb.append(API_KEY);\r\n        sb.append(SLASH);\r\n        sb.append(URLEncoder.encode(query));\r\n        return sb.toString();\r\n    }\r\n    \r\n    public ArrayList&lt;E&gt; retrieveFirstResults(ArrayList&lt;E&gt; list, int maxResults) {\r\n        ArrayList&lt;E&gt; newList = new ArrayList&lt;E&gt;();\r\n        int count = Math.min(list.size(), maxResults);\r\n        for (int i=0; i&lt;count; i++) {\r\n            newList.add(list.get(i));\r\n        }\r\n        return newList;\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>The GenericSeeker class denotes that it is able to find results of a particular class and the extending classes will have to provide concrete implementations for the appropriate classes. The HttpRetriever and XmlParser objects from our previous tutorials will be used. Remember that the <a href=\"http:\/\/api.themoviedb.org\/2.1\/\">TMDb API<\/a> uses similar URLs for movies and person searching:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<ul>\n<li><a href=\"http:\/\/api.themoviedb.org\/2.1\/methods\/Movie.search\">Movie.search<\/a> (<a href=\"http:\/\/api.themoviedb.org\/2.1\/methods\/Movie.search\">http:\/\/api.themoviedb.org\/2.1\/methods\/Movie.search<\/a>) Provides the easiest and quickest way to search for a movie.<\/li>\n<li><a href=\"http:\/\/api.themoviedb.org\/2.1\/methods\/Person.search\">Person.search<\/a> (<a href=\"http:\/\/api.themoviedb.org\/2.1\/methods\/Person.search\">http:\/\/api.themoviedb.org\/2.1\/methods\/Person.search<\/a>) Is used to search for an actor, actress or production member.<\/li>\n<\/ul>\n<p>Thus, we are using a common base URL and the extending classes have to provide the additional path by implementing the \u201cretrieveSearchMethodPath\u201d method. Two more methods have to be implemented, find(String) and find(String, int), which both return an <a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/util\/ArrayList.html\">ArrayList<\/a> of objects with the appropriate class. The second one can be used in order to narrow down the total number of results. This could be helpful because the API typically return results which are not very relevant to the search query and could be discarded in order to have some performance gain. Finally, do not forget to replace the value of the API_KEY variable with a valid key from the <a href=\"http:\/\/www.themoviedb.org\/account\/signup\">TMDb site<\/a>.<\/p>\n<p>Next, we have the code for the two child classes, MovieSeeker and PersonSeeker. The classes are very similar, so I only present one here for reasons of brevity:<\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.android.apps.moviesearchapp.services;\r\n\r\nimport java.util.ArrayList;\r\n\r\nimport android.util.Log;\r\n\r\nimport com.javacodegeeks.android.apps.moviesearchapp.model.Movie;\r\n\r\npublic class MovieSeeker extends GenericSeeker&lt;Movie&gt; {\r\n        \r\n    private static final String MOVIE_SEARCH_PATH = \"Movie.search\/\";\r\n    \r\n    public ArrayList&lt;Movie&gt; find(String query) {\r\n        ArrayList&lt;Movie&gt; moviesList = retrieveMoviesList(query);\r\n        return moviesList;\r\n    }\r\n    \r\n    public ArrayList&lt;Movie&gt; find(String query, int maxResults) {\r\n        ArrayList&lt;Movie&gt; moviesList = retrieveMoviesList(query);\r\n        return retrieveFirstResults(moviesList, maxResults);\r\n    }\r\n    \r\n    private ArrayList&lt;Movie&gt; retrieveMoviesList(String query) {\r\n        String url = constructSearchUrl(query);\r\n        String response = httpRetriever.retrieve(url);\r\n        Log.d(getClass().getSimpleName(), response);\r\n        return xmlParser.parseMoviesResponse(response);\r\n    }\r\n\r\n    @Override\r\n    public String retrieveSearchMethodPath() {\r\n        return MOVIE_SEARCH_PATH;\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>The private method \u201cretrieveMoviesList\u201d is the core of that class. It first constructs the URL for the API call and the executes the HTTP request using the HttpRetriever class instance. If the request is successful, the XML response is feeded to the XmlParser service which is responsible for mapping the response to the Movie model object. The find(String) and find(String, int) methods are actually wrappers to the private method.<\/p>\n<p>We are now ready to use the search services from our main Activity. First we create an instance of those services as follows:<\/p>\n<pre class=\"brush:java\">...\r\nprivate GenericSeeker&lt;Movie&gt; movieSeeker = new MovieSeeker();\r\nprivate  GenericSeeker&lt;Person&gt; personSeeker = new PersonSeeker();\r\n...\r\n<\/pre>\n<p>As mentioned in the beginning of the article, the call to the find methods of those classes should be performed in a thread other than the UI thread. It is now time to create our AsyncTask implementation, which is the following for Movie searching:<\/p>\n<pre class=\"brush:java\">...\r\nprivate class PerformMovieSearchTask extends AsyncTask&lt;String, Void, List&lt;Movie&gt;&gt; {\r\n\r\n   @Override\r\n   protected List&lt;Movie&gt; doInBackground(String... params) {\r\n      String query = params[0];\r\n      return movieSeeker.find(query);\r\n   }\r\n   \r\n   @Override\r\n   protected void onPostExecute(final List&lt;Movie&gt; result) {         \r\n      runOnUiThread(new Runnable() {\r\n      @Override\r\n      public void run() {\r\n         if (progressDialog!=null) {\r\n            progressDialog.dismiss();\r\n            progressDialog = null;\r\n         }\r\n         if (result!=null) {\r\n               for (Movie movie : result) {\r\n                  longToast(movie.name + \" - \" + movie.rating);\r\n               }\r\n            }\r\n      }\r\n       });\r\n   }\r\n      \r\n}\r\n...\r\n<\/pre>\n<p>First we declare that our implementation extends the class AsyncTask&gt;. This signature means that the type of the parameters sent to the task upon execution are of type <a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/lang\/String.html\">String<\/a>, that no progress units will be published during the background computation (denoted by <a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/lang\/Void.html\">Void<\/a>) and that the result of the background computation is of type <a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/util\/List.html\">List<\/a> which holds Movie objects. In the <a href=\"http:\/\/developer.android.com\/reference\/android\/os\/AsyncTask.html#doInBackground%28Params...%29\">doInBackground<\/a> method, we perform the actual HTTP data retrieval and then, on the <a href=\"http:\/\/developer.android.com\/reference\/android\/os\/AsyncTask.html#onPostExecute%28Result%29\">onPostExecute<\/a> method we present the results in the form of <a href=\"http:\/\/developer.android.com\/reference\/android\/widget\/Toast.html\">Toast<\/a> notifications. Note that another task class is named \u201cPerformPersonSearchTask\u201d is also created and is used for performing person searching.<\/p>\n<p>Note that a <a href=\"http:\/\/developer.android.com\/reference\/android\/app\/ProgressDialog.html\">ProgressDialog<\/a> widget is used in order to let the user know that data retrieval takes place and that he should be patient. The progress dialog is declared cancelable in its <a href=\"http:\/\/developer.android.com\/reference\/android\/app\/ProgressDialog.html#show%28android.content.Context,%20java.lang.CharSequence,%20java.lang.CharSequence,%20boolean,%20boolean%29\">factory method<\/a> so that the user can cancel the task upon request. The relevant code is the following:<\/p>\n<pre class=\"brush:java\">...\r\nprivate void performSearch(String query) {\r\n        \r\n        progressDialog = ProgressDialog.show(MovieSearchAppActivity.this,\r\n                \"Please wait...\", \"Retrieving data...\", true, true);\r\n        \r\n        if (moviesSearchRadioButton.isChecked()) {\r\n            PerformMovieSearchTask task = new PerformMovieSearchTask();\r\n            task.execute(query);\r\n            progressDialog.setOnCancelListener(new CancelTaskOnCancelListener(task));\r\n        }\r\n        else if (peopleSearchRadioButton.isChecked()) {\r\n            PerformPersonSearchTask task = new PerformPersonSearchTask();\r\n            task.execute(query);\r\n            progressDialog.setOnCancelListener(new CancelTaskOnCancelListener(task));\r\n        }\r\n        \r\n    }\r\n...\r\n<\/pre>\n<p>We also provide an implementation for the <a href=\"http:\/\/developer.android.com\/reference\/android\/content\/DialogInterface.OnCancelListener.html\">OnCancelListener<\/a> of the progress dialog with the sole purpose of canceling the relevant task. The code is the following:<\/p>\n<pre class=\"brush:java\">...\r\nprivate class CancelTaskOnCancelListener implements OnCancelListener {\r\n        private AsyncTask&lt;?, ?, ?&gt; task;\r\n        public CancelTaskOnCancelListener(AsyncTask&lt;?, ?, ?&gt; task) {\r\n            this.task = task;\r\n        }\r\n        @Override\r\n        public void onCancel(DialogInterface dialog) {\r\n            if (task!=null) {\r\n                task.cancel(true);\r\n            }\r\n        }\r\n    }\r\n...\r\n<\/pre>\n<p>Let&#8217;s see the results of our code so far. Use Eclipse to run the project&#8217;s configuration and launch the application. Provide a query string in the edit text and hit the button to perform the search. The progress dialog appears notifying for the request operation as in the following image:<\/p>\n<p><a href=\"http:\/\/4.bp.blogspot.com\/_piNjpdpJZXA\/TM2rzpX-vwI\/AAAAAAAAALY\/eLXZcDccAvE\/s1600\/01-data-retrieval.png\"><img decoding=\"async\" alt=\"\" border=\"0\" src=\"http:\/\/4.bp.blogspot.com\/_piNjpdpJZXA\/TM2rzpX-vwI\/AAAAAAAAALY\/eLXZcDccAvE\/s320\/01-data-retrieval.png\" style=\"cursor: pointer;height: 320px;margin: 0px auto 10px;text-align: center;width: 275px\" \/><\/a><\/p>\n<p>The user is able to cancel the task at any time by hitting the \u201cBack\u201d button. If the operation is successful, the callback method will get triggered and a toast for each result will be presented to the user as in the following image:<\/p>\n<p><a href=\"http:\/\/1.bp.blogspot.com\/_piNjpdpJZXA\/TM2r6vmr7mI\/AAAAAAAAALg\/lx8o3kvqDYE\/s1600\/02-data-presentation.png\"><img decoding=\"async\" alt=\"\" border=\"0\" src=\"http:\/\/1.bp.blogspot.com\/_piNjpdpJZXA\/TM2r6vmr7mI\/AAAAAAAAALg\/lx8o3kvqDYE\/s320\/02-data-presentation.png\" style=\"cursor: pointer;height: 320px;margin: 0px auto 10px;text-align: center;width: 254px\" \/><\/a><\/p>\n<p>This concludes the fourth part of the tutorial series. You can download <a href=\"http:\/\/dl.dropbox.com\/u\/7215751\/JavaCodeGeeks\/AndroidFullAppTutorialPart04\/AndroidMovieSearchAppProject_Part04.zip\">here<\/a> the Eclipse project created so far.<\/p>\n<div style=\"margin-bottom: 0px;margin-left: 0px;margin-right: 0px;margin-top: 0px\"><strong><i>Related Articles :<\/i><\/strong><\/div>\n<ul>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/10\/android-full-application-tutorial.html\">\u201cAndroid Full Application Tutorial\u201d series<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/09\/android-text-to-speech-application.html\">Android Text-To-Speech Application<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/09\/android-reverse-geocoding-yahoo-api.html\">Android Reverse Geocoding with Yahoo API &#8211; PlaceFinder<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/09\/android-location-based-services.html\">Android Location Based Services Application \u2013 GPS location<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/06\/embracing-android-awesomeness-quick.html\">Install Android OS on your PC with VirtualBox<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/06\/embracing-android-awesomeness-quick.html\">Embracing the Android awesomeness: A quick overview<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing movies\/actors searching over the internet. In the first part of the series (\u201cMain Activity UI\u201d), we created the Eclipse project and set up a basic interface for the main activity of the &hellip;<\/p>\n","protected":false},"author":3,"featured_media":46,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[83,29],"class_list":["post-315","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android-core","tag-android-tutorial","tag-eclipse"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2010-10-31T20:01:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T19:20:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Ilias Tsagklis\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ilias Tsagklis\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html\"},\"author\":{\"name\":\"Ilias Tsagklis\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9a83496b285d30c61e8a674625c1350e\"},\"headline\":\"Android Full App, Part 4: Performing the API request asynchronously from the main activity\",\"datePublished\":\"2010-10-31T20:01:00+00:00\",\"dateModified\":\"2012-10-21T19:20:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html\"},\"wordCount\":1213,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"keywords\":[\"Android Tutorial\",\"Eclipse\"],\"articleSection\":[\"Android Core\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html\",\"name\":\"Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"datePublished\":\"2010-10-31T20:01:00+00:00\",\"dateModified\":\"2012-10-21T19:20:05+00:00\",\"description\":\"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2010\\\/10\\\/android-full-app-part-4-asynchronous.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Android\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/android\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Android Core\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/android\\\/android-core\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Android Full App, Part 4: Performing the API request asynchronously from the main activity\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9a83496b285d30c61e8a674625c1350e\",\"name\":\"Ilias Tsagklis\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g\",\"caption\":\"Ilias Tsagklis\"},\"description\":\"Ilias is a software developer turned online entrepreneur. He is co-founder and Executive Editor at Java Code Geeks.\",\"sameAs\":[\"http:\\\/\\\/www.iliastsagklis.com\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/iliastsagklis\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/ilias-tsagklis\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks","description":"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html","og_locale":"en_US","og_type":"article","og_title":"Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks","og_description":"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing","og_url":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2010-10-31T20:01:00+00:00","article_modified_time":"2012-10-21T19:20:05+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","type":"image\/jpeg"}],"author":"Ilias Tsagklis","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Ilias Tsagklis","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html"},"author":{"name":"Ilias Tsagklis","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9a83496b285d30c61e8a674625c1350e"},"headline":"Android Full App, Part 4: Performing the API request asynchronously from the main activity","datePublished":"2010-10-31T20:01:00+00:00","dateModified":"2012-10-21T19:20:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html"},"wordCount":1213,"commentCount":6,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","keywords":["Android Tutorial","Eclipse"],"articleSection":["Android Core"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html","url":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html","name":"Android Full App, Part 4: Performing the API request asynchronously from the main activity - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","datePublished":"2010-10-31T20:01:00+00:00","dateModified":"2012-10-21T19:20:05+00:00","description":"This is the fourth part of the \u201cAndroid Full Application Tutorial\u201d series. The complete application aims to provide an easy way of performing","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2010\/10\/android-full-app-part-4-asynchronous.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Android","item":"https:\/\/www.javacodegeeks.com\/category\/android"},{"@type":"ListItem","position":3,"name":"Android Core","item":"https:\/\/www.javacodegeeks.com\/category\/android\/android-core"},{"@type":"ListItem","position":4,"name":"Android Full App, Part 4: Performing the API request asynchronously from the main activity"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9a83496b285d30c61e8a674625c1350e","name":"Ilias Tsagklis","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/43505f28bb49f6e290c24be0b209ccc1af350f0f6587025ffd4847ef44bf6b78?s=96&d=mm&r=g","caption":"Ilias Tsagklis"},"description":"Ilias is a software developer turned online entrepreneur. He is co-founder and Executive Editor at Java Code Geeks.","sameAs":["http:\/\/www.iliastsagklis.com\/","https:\/\/www.linkedin.com\/in\/iliastsagklis"],"url":"https:\/\/www.javacodegeeks.com\/author\/ilias-tsagklis"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=315"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/315\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/46"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}