HTTP requests and AsyncTask class
The Steps
1.App ask’s its private AsyncTask class to get the data myAsycnTaskObj.execute(params)
2.AsyncTask call’s its own doInBackground(params) method
3.doInBackground(params) makes HTTPURLConnection to “Server” asking for data
4.Server gets requests, processes it and returns results (here JSON but, could be any kind of data)
5.AsyncTask gets called back with data from #4 in onPostExecute(results)
6.onPostExecute() will make calls to its OUTER class parent (the fragment or Activity that it is inside) and invoke that Activity’s methods to either process the data or show it in the GUI
An Example -- dump Yelp's San Jose front page into a TextView in a silly app
THE INTERFACE
|
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="computervision.grewe.httpassynctask.MainActivity"> <TextView android:id="@+id/textDump" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="data to appear here" />
</RelativeLayout>
|
|
THE MANIFEST FILE
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="computervision.grewe.httpassynctask">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
</manifest>
|
THE CODE
package computervision.grewe.httpassynctask;
import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView;
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL;
import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView dumpText;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
//grab TextView dumpText = (TextView) findViewById(R.id.textDump); //grab data from Yelp only if we have connectivity ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { // fetch data getYelpdata(); } else { // display error dumpText.setText("No Connection"); } }
//go to yelp api rest URL and grab data --initially no OAuth protected void getYelpdata() { //call ASync Task class to process getting data //String stringUrl = "http://api.yelp.com/v2/search?term=food&location=San+Francisco"; String stringUrl = "https://www.yelp.com/san-jose";
new DownloadWebpageTask().execute(stringUrl);
}
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.textDump) { return true; } return super.onOptionsItemSelected(item); }
//private class to do ASYNC getting of yelp data // Uses AsyncTask to create a task away from the main UI thread. This task takes a // URL string and uses it to create an HttpUrlConnection. Once the connection // has been established, the AsyncTask downloads the contents of the webpage as // an InputStream. Finally, the InputStream is converted into a string, which is // displayed in the UI by the AsyncTask's onPostExecute method. private class DownloadWebpageTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url. try { return downloadUrl(urls[0]); } catch (IOException e) { return "Unable to retrieve web page. URL may be invalid."; } } // onPostExecute displays the results of the AsyncTask. @Override protected void onPostExecute(String result) { dumpText.setText(result); }
//this is the workhorse method that does the HTTPRequest // Given a URL, establishes an HttpUrlConnection and retrieves // the web page content as a InputStream, which it returns as // a string. private String downloadUrl(String myurl) throws IOException { InputStream is = null; // Only display the first 500 characters of the retrieved // web page content. int len = 500;
try { URL url = new URL(myurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(10000 /* milliseconds */); conn.setConnectTimeout(15000 /* milliseconds */); conn.setRequestMethod("GET"); conn.setDoInput(true); // Starts the query conn.connect(); int response = conn.getResponseCode(); Log.d("ASyncTask", "The response is: " + response); is = conn.getInputStream();
// Convert the InputStream into a string String contentAsString = readIt(is, len); return contentAsString;
// Makes sure that the InputStream is closed after the app is // finished using it. } finally { if (is != null) { is.close(); } } }
// Reads an InputStream and converts it to a String. public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException { Reader reader = null; reader = new InputStreamReader(stream, "UTF-8"); char[] buffer = new char[len]; reader.read(buffer); return new String(buffer); }
}
}
|
|