Sie sind auf Seite 1von 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

Android: Session Two


Part 1: DelayedWork
The goal of this exercise is to use a thread to do some work in background, so that the UI is still
responsive.
Well be making an application that do the following tasks in background
Sleep and then display a message
Download an image and display it

First step: Create the UI


Create a DelayedWork android project, in SDK 2.3.3
The interface needs to have its default TextView at the top, 2 buttons and an ImageView. Here is a
screenshot of it:

PAGE 1 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

Create the user interface.


Change the root layout to Linear Layout.
For the ImageView, set the following fields:
layout_width and layout_height to 100dp
src to @drawable/ic_launcher (a resource that is part of the default Android project)

The Hierarchy Viewer

There is a very useful tool called Hierarchy Viewer that let you see how the UI of a running activity is
structured.
This tool is part of the SDK so it can be found in the SDK/Tools directory, but recently Google included
it in the ADT plugin. As such, its now accessible directly in Eclipse [Windows->Open perspective>Other->Hierarchy View].
Launch the hierarchy viewer
Your application has to be running for the tool to see it. If you dont see your application, refresh the list of
currently running activities in the Windows tab.
To give you a better understanding of how our application UI is structured, here is its hierarchy view.

As you can see we have multiple nested linearLayouts:


The first one is a horizontal LinearLayout that contains the ImageView and a LinearLayout
The second one is a vertical LinearLayout with the 2 buttons

PAGE 2 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

Second step: DelayedMessage


The UI thread is the only one allowed to modify the UI. In android, the easiest way to do work in
background and still be able to access the UI is to use the AsyncTask class because it will do the thread
work for you.
Inside your MainActivity class, create a new subclass of AsyncTask called DelayedMessage.
You will need to implement: the following methods:
doInBackground(): called when the AsyncTask is executed; its the actual work you want to do in

background

onPostExecute(): called when the AsyncTask finishes; its the place where you are allowed to

access your UI

An AsyncTask<Params, Progress, Result> class is defined by 3 generics types:


Params: the type of the parameters sent to the task upon execution
Progress: the type of the progress units published during the background computation
Result: the type of the result of the background computation.
As an example here is a code that logs the string given as parameter to the AsyncTask:
class DelayedMessage extends AsyncTask<String, Integer, String>
{





@Override
protected String doInBackground(String... params)
{

//your code here

return params[0];
}

@Override
protected void onPostExecute(String result)
{

//your code here

Log.d(TAG, result);
}

And here is how you call it in your code:


DelayedMessage foobar = new DelayedMessage();
foobar.execute("hello world");

PAGE 3 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

Use the doInBackground() method to sleep 1000 ms and then display a toast notication in the
onPostExecute() method.
Use your DelayedMessage class to display the message when the DelayedMessage button is clicked.

Third step: BackgroundImageDl


Now we want to be able to download an image when the DelayedSmiley button is pressed without
blocking the UI.
First of all, you have to add a uses-permission to be allowed to use internet in your application.
On the device, the user has to grant permissions to each application when its installed. On the emulator,
the application already has those rights, so no question is asked.
Add the following in your AndroidManifest.xml file, before the closing tag:
<uses-permission android:name="android.permission.INTERNET" />

Create a new BackgroundImageDl class inside your activity the same way your created your
previous DelayedMessage class.
Here some code to download an image from a URL string and generate a Drawable object that you can
display in your ImageView:
URL url = new URL(stringUrl);
//extra sleep to simulate a longer download
Thread.sleep(1000);
Object content = url.getContent();
InputStream is = (InputStream) content;
Drawable d = Drawable.createFromStream(is, "src");

Your doInBackground() method has to download the image from the URL string that is passed to the
AsyncTask.Execute() method, generate a Drawable object and then return it so that the
onPostExecute() method can display it.
Download and display the following image when the user clicks on the DelayedSmiley
url: http://education.3ie.fr/android/smiley.png

Fourth step: Refactoring

PAGE 4 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

The way we added the BackgroundImageDl class in our main Java file is eective but kind of ugly. A
better way to do it is to use a separate class for your AsyncTask.
Since we are outside of our Activity, we dont have the reference to the imageView so we have to give it to
this class we are creating.
Here is what your class is going to look like. You have to fill the blanks and then use this ImageDownload
class instead of our previous DelayedMessage.
public class ImageDownloader
{

public void download(String url, ImageView imageView)

{


BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);


task.execute(url);

}


class BitmapDownloaderTask extends AsyncTask<String, Integer, Drawable>


{

private final ImageView imageViewReference;

public BitmapDownloaderTask(ImageView imageView) {



//TODO: save the reference to the imageView
}

@Override
// Actual download method, run in the task thread
protected Drawable doInBackground(String... params) {

//TODO
}

@Override
protected void onProgressUpdate(Integer... values) {

//nothing to do here
}

@Override
protected void onPostExecute(Drawable d) {

//TODO
}

PAGE 5 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

Part 2: RelativeLayout
First step: RelativeLayout presentation
This step is not an exercise, just some explanations.
The RelativeLayout works in such a way that the programmer describes how the various widgets are
related to one another. It is very powerful but not as easy to understand as the LinearLayout.
The best way to explain it is to look at a simple example.
We want to make this simple UI that cannot be done with only one LinearLayout:

To make this kind of interface with only LinearLayouts, we would have to create multiple nested
LinearLayouts because of the 2 buttons we want to have next to each other.
Here is how you could structure your layout (not the complete XML):
<LinearLayout android:orientation="vertical" >
<EditText />
<LinearLayout android:orientation="horizontal" >
<Button />
<Button />
</LinearLayout>
</LinearLayout>

In RelativeLayout, we can easily place the 2 buttons next 2 each other without having to use another
nested Layout, so the UI is faster to render.
Here is how you could structure the previous UI in relative layout (not the complete XML):

PAGE 6 OF 7

ANDROID: TP1

APPING-MASTERS-2013-VERDIER

<RelativeLayout >
<EditText
android:id="@+id/editText1"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button1"
android:layout_alignParentLeft="true"
android:layout_below="@+id/editText1" />
<Button
android:id="@+id/button2"
android:layout_below="@+id/editText1"
android:layout_toRightOf="@+id/button1" />
</RelativeLayout>

Notice how the button2 is configured to be below the editText and to the right of the button1.

Second step: DelayedMessage UI


You are going the redo the UI for the previous exercise . The interface hierarchy in relative layout will be
much more simple than the previously nested LinearLayout. You only need a root RelativeLayout to host
all the others widgets.
Modify your UI to make it use a relative layout.
The screenshot shows you the way you UI should be structured.

PAGE 7 OF 7

Das könnte Ihnen auch gefallen