After clicking the button that initiates the download, Android will give your application no more than a few seconds to respond to that input event. Otherwise, it’ll kill it and raise the previously mentioned ANR exception. For BroadcastReceivers, Android
is more forgiving and waits longer before pulling the plug, but it also monitors their
execution time.
SimpleImageDownload.java uses java.lang.Thread to download an image file:
public class SimpleImageDownload extends Activity { private Runnable imageDownloader=new Runnable(){ @Override public void run() { // TODO Auto-generated method stub try { URL url=new URL("http://www.android.com/images/froyo.png"); Bitmap image=BitmapFactory.decodeStream(url.openStream()); if (image != null) { Log.i("DL", "Successfully retrieved file!"); } else { Log.i("DL", "Failed decoding file from stream"); } } catch (Exception e) { Log.i("DL", "Failed downloading file!"); e.printStackTrace(); } } }; private void startDownload(){ new Thread(imageDownloader,"Download thread").start(); TextView statusText=(TextView)findViewById(R.id.status); statusText.setText("Download started..."); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
The layout file main.xml defines the button and the status text view
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Download file" android:onClick="startDownload"/> <TextView android:id="@+id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="click to start"/> </LinearLayout>
It turns out that a thread lives as long as it takes its run method to terminate. It’s not bound to the component that started it, and can even outlive it. This has a curious implication: it means that you must be extremely cautious about keeping references to
things such as an Activity in your thread because the Activity may finish before your thread terminates. The runtime will keep the Activity object around because you hold a strong reference to it, but its lifecycle from the perspective of the framework has
ended!