Version 1.5
Copyright © 2009, 2010, 2011, 2012 Lars Vogel
06.01.2012
| Revision History | ||
|---|---|---|
| Revision 0.1 | 19.07.2010 | Lars Vogel |
| Created | ||
| Revision 0.2 - 1.6 | 30.08.2010 - 06.11.2012 | Lars Vogel |
| bug fixes and enhancements | ||
Table of Contents
Android contains the standard Java network
java.net
package which can be used to access network resources. Android
also
contains the
Apache HttpClient library.
The base class for HTTP network access in the
java.net
package is that
HttpURLConnection
class
.
It used to be that the preferred access of the network would be
the
Apache HttpClient library. September 2011 the Android development
team published
a blog entry
in which they suggest to prefer
HttpURLConnection
in future Android projects as they constantly improving this
implementation.
Within Android development you should avoid performing long
running
operations on the UI thread. This includes file and network
access.
StrictMode
allows to setup policies in your application to avoid doing
incorrect
things. As of Android 3.0 (Honeycomb)
StrictMode
is configured to crash with an
NetworkOnMainThreadException
exception if network access happens in the UI thread.
While you should do network access in a background thread this tutorial will avoid this to allow the user to learn network access independent from background processing.
If you targeting Android 3.0 or higher you can turn this check of via
the following code at beginning of your
onCreate()
method of your
Activity.
StrictMode.ThreadPolicy policy = new StrictMode. ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);
HttpURLConnection
is a general-purpose, lightweight HTTP client suitable for most
applications. This API is recommended by the Android development
team
to use in newer applications, as this interface get constantly
improved.
In the latest version
HttpURLConnection
supports transparent response compression (via the header
Accept-Encoding: gzip, Server Name Indication (extension of SSL and TLS) and a response
cache.
The API is relatively straigh forward. For example to retrieve the webpage www.vogella.de.
URL url = new URL("http://www.vogella.de/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); try { InputStream in = new BufferedInputStream(urlConnection.getInputStream()); readStream(in); finally { urlConnection.disconnect(); } }
Android contains the Apache HttpClient library.
You can either use
the
DefaultHttpClient
or
AndroidHttpClient
to setup the HTTP client.
DefaultHttpClient
is the standard HttpClient and uses the
SingleClientConnManager
class to handle HTTP connections.
SingleClientConnManager
is not thread-safe, this means that access to it via several threads
will create problems.
The following is an example an HTTP Get request via
HttpClient.
HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet("http://www.vogella.de"); HttpResponse response = client.execute(request); // Get the response BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); String line = ""; while ((line = rd.readLine()) != null) { textView.append(line); }
AndroidHttpClient
is a special implementation of
DefaultHttpClient
which is pre-configured for Android.
AndroidHttpClient
was introduced in Android 2.2.
An instance can be
received via the
newInstance()
method
which allows to specify the user agent as parameter.
AndroidHttpClient
supports SSL and has utility methods
for GZIP
compressed data. It
registers the
ThreadSafeClientConnManager
which allows thread safe HTTP access via a managed connection pool.
AndroidHttpClient
also applied reasonable default for timeouts and socket buffer sizes.
It also supports HTTPS by
default.
Create the project
de.vogella.android.network.html
with the
activity
ReadWebpage. Change the layout
main.xml
to the following.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" > </LinearLayout> <EditText android:id="@+id/address" android:layout_width="fill_parent" android:layout_height="wrap_content" > </EditText> <Button android:id="@+id/ReadWebPage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="myClickHandler" android:text="Read Webpage" > </Button> <TextView android:id="@+id/pagetext" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" > </TextView> </LinearLayout>
Add the permission
android.permission.INTERNET
to
the
AndroidManifest.xml
file to allow your application to access the
Internet.
Create the following code to read a webpage and show the HTML code in the TextView.
This example also demonstrate the usage of Android preferences to
store
user data. The URL which the user has typed is stored in the
preferences in the
onPause()
method. This method is called whenever the
Activity
is send into the background.
package de.vogella.android.network.html; import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; public class ReadWebpage extends Activity { private static final String PREFERENCES = "PREFERENCES"; private static final String URL = "url"; private String lastUrl; private EditText urlText; private TextView textView;/** Called when the activity is first created. */@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); urlText = (EditText) findViewById(R.id.address); textView = (TextView) findViewById(R.id.pagetext); loadPreferences(); urlText.setText(lastUrl); }/** * Demonstrates loading of preferences The last value in the URL string will * be loaded */private void loadPreferences() { SharedPreferences preferences = getSharedPreferences(PREFERENCES, Activity.MODE_PRIVATE); // Set this to the Google Homepage lastUrl = preferences.getString(URL, "http://209.85.229.147"); } @Override protected void onPause() { super.onPause(); SharedPreferences preferences = getSharedPreferences(PREFERENCES, Activity.MODE_PRIVATE); Editor preferenceEditor = preferences.edit(); preferenceEditor.putString(URL, urlText.getText().toString()); // You have to commit otherwise the changes will not be remembered preferenceEditor.commit(); } public void myClickHandler(View view) { switch (view.getId()) { case R.id.ReadWebPage: try { textView.setText(""); HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(urlText.getText().toString()); HttpResponse response = client.execute(request); // Get the response BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); String line = ""; while ((line = rd.readLine()) != null) { textView.append(line); } } catch (Exception e) { System.out.println("Nay, did not work"); textView.setText(e.getMessage()); } break; } } }
Obviously the network on an Android device is not always
available. You
can check the network is currently available via
the following code.
This requires the
ACCESS_NETWORK_STATE
permission.
public boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); // if no network is available networkInfo will be null, otherwise check if we are connected if (networkInfo != null && networkInfo.isConnected()) { return true; } return false; }
This chapter is only relevant for you if you are testing with the Android similator behind a proxy. In class you are behind a proxy during your testing you can set the proxy via the class "Settings". For example you could add the following line to your onCreate method in your activity.
Settings.System.putString(getContentResolver(), Settings.System.HTTP_PROXY, "myproxy:8080");
To change the proxy settings you have to have the permission "android.permission.WRITE_SETTINGS" in "AndroidManifest.xml".

Network connection fail frequently especially for mobile clients. For example if you switch from Wifi to 3G then an existing network connection will break and you need to retry the request.
The Apache HttpClient has an default
DefaultHttpRequestRetryHandler
object registered which will per default 3 times retry a failed
connection. The problem is that switching from one network to another
make take a little while and
DefaultHttpRequestRetryHandler
will retry immediately.
To work around this issue you can implement your own version of
DefaultHttpRequestRetryHandler
in which you wait a pre-defined time.
For example the implementation could look like:
AbstractHttpClient client = (AbstractHttpClient) new DefaultHttpClient(); DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (!super.retryRequest(exception, executionCount, context)) { return false; } // Retry but wait a bit try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return true; } }; client.setHttpRequestRetryHandler(retryHandler);
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.de Google Group. I have created a short list how to create good questions which might also help you.
Introduction to Android Development
Android Location API and Google Maps
Crest Framework to access rest services, works also on Android
Eclipse RCP Training (German) Eclipse RCP Training with Lars Vogel
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system