diff --git a/docs/html/training/notepad/codelab/NotepadCodeLab.zip b/docs/html/training/notepad/codelab/NotepadCodeLab.zip deleted file mode 100644 index cd30f291587a7..0000000000000 Binary files a/docs/html/training/notepad/codelab/NotepadCodeLab.zip and /dev/null differ diff --git a/docs/html/training/notepad/index.jd b/docs/html/training/notepad/index.jd deleted file mode 100644 index 507b232e79087..0000000000000 --- a/docs/html/training/notepad/index.jd +++ /dev/null @@ -1,136 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Tutorial -parent.title=Tutorials -@jd:body - - -

This tutorial on writing a notepad application gives you a "hands-on" introduction -to the Android framework and the tools you use to build applications on it. -Starting from a preconfigured project file, it guides you through the process of -developing a simple notepad application and provides concrete examples of how to -set up the project, develop the application logic and user interface, and then -compile and run the application.

- -

The tutorial presents the application development as a set of -exercises (see below), each consisting of several steps. You should follow -the steps in each exercise to gradually build and refine your -application. The exercises explain each step in detail and provide all the -sample code you need to complete the application.

- -

When you are finished with the tutorial, you will have created a functioning -Android application and will have learned many of the most important -concepts in Android development.

- - -

Who Should Use this Tutorial

- -

This tutorial is designed for experienced developers, especially those with -knowledge of the Java programming language. If you haven't written Java -applications before, you can still use the tutorial, but you might need to work -at a slower pace.

- -

Also note that this tutorial uses -the Eclipse development environment, with the Android plugin installed. If you -are not using Eclipse, you can follow the exercises and build the application, -but you will need to determine how to accomplish the Eclipse-specific -steps in your environment.

- - -

Preparing for the Exercises

- -

The tutorial assumes that you have some familiarity with basic Android -application concepts and terminology. If you are not, you -should read Application -Fundamentals before continuing.

- -

This tutorial also builds on the introductory information provided in the -Building Your First App -tutorial, which explains how to set up your Eclipse environment -for building Android applications. We recommend you complete the Hello World -tutorial before starting this one.

- -

To prepare for this lesson:

- -
    -
  1. Download the project - exercises archive (.zip).
  2. -
  3. Unpack the archive file to a suitable location on your machine.
  4. -
  5. Open the NotepadCodeLab folder.
  6. -
- -

Inside the NotepadCodeLab folder, you should see six project -files: Notepadv1, - Notepadv2, Notepadv3, - Notepadv1Solution, Notepadv2Solution - and Notepadv3Solution. The Notepadv# projects are -the starting points for each of the exercises, while the -Notepadv#Solution projects are the exercise - solutions. If you are having trouble with a particular exercise, you - can compare your current work against the exercise solution.

- - -

Exercises

- -

The table below lists the tutorial exercises and describes the development -areas that each covers. Each exercise assumes that you have completed any -previous exercises.

- - - - - - - - - - - - - - - - - - -
Exercise -1Start here. Construct a simple notes list that lets the user add new notes but not -edit them. Demonstrates the basics of ListActivity and creating -and handling - menu options. Uses a SQLite database to store the notes.
Exercise 2Add a second Activity to the -application. Demonstrates constructing a -new Activity, adding it to the Android manifest, passing data between the -activities, and using more advanced screen layout. Also shows how to -invoke another Activity to return a result, using -startActivityForResult().
Exercise 3Add handling of life-cycle events to -the application, to let it -maintain application state across the life cycle.
Extra -CreditDemonstrates how to use the Eclipse -debugger and how you can use it to -view life-cycle events as they are generated. This section is optional but -highly recommended.
- - - -

Other Resources and Further Learning

- diff --git a/docs/html/training/notepad/notepad-ex1.jd b/docs/html/training/notepad/notepad-ex1.jd deleted file mode 100644 index f680f1505d5f5..0000000000000 --- a/docs/html/training/notepad/notepad-ex1.jd +++ /dev/null @@ -1,583 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Exercise 1 -parent.title=Notepad Tutorial -parent.link=index.html -@jd:body - - -

In this exercise, you will construct a simple notes list that lets the -user add new notes but not edit them. The exercise demonstrates:

- - -
- - [Exercise 1] - [Exercise 2] - [Exercise 3] - [Extra Credit] -
- - - -

Step 1

- -

Open up the Notepadv1 project in Eclipse.

- -

Notepadv1 is a project that is provided as a starting point. It - takes care of some of the boilerplate work that you have already seen if you - followed the Hello, - World tutorial.

- -
    -
  1. - Start a new Android Project by clicking File > - New > Android Project.
  2. -
  3. - In the New Android Project dialog, select Create project from existing source.
  4. -
  5. - Click Browse and navigate to where you copied the NotepadCodeLab - (downloaded during setup) - and select Notepadv1.
  6. -
  7. - The Project Name and other properties should be automatically filled for you. - You must select the Build Target—we recommend selecting a target with the - lowest platform version available. Also add an integer to the Min SDK Version field - that matches the API Level of the selected Build Target.
  8. -
  9. - Click Finish. The Notepadv1 project should open and be - visible in your Eclipse package explorer.
  10. -
- -

If you see an error about AndroidManifest.xml, or some - problems related to an Android zip file, right click on the project and - select Android Tools > Fix Project Properties. - (The project is looking in the wrong location for the library file, - this will fix it for you.)

- -

Step 2

- - - -

Take a look at the NotesDbAdapter class — this class is provided to - encapsulate data access to a SQLite database that will hold our notes data - and allow us to update it.

-

At the top of the class are some constant definitions that will be used in the application - to look up data from the proper field names in the database. There is also a database creation - string defined, which is used to create a new database schema if one doesn't exist already.

-

Our database will have the name data, and have a single table called - notes, which in turn has three fields: _id, title and - body. The _id is named with an underscore convention used in a number of - places inside the Android SDK and helps keep a track of state. The _id - usually has to be specified when querying or updating the database (in the column projections - and so on). The other two fields are simple text fields that will store data. -

-

The constructor for NotesDbAdapter takes a Context, which allows it to communicate with aspects - of the Android operating system. This is quite common for classes that need to touch the - Android system in some way. The Activity class implements the Context class, so usually you will just pass - this from your Activity, when needing a Context.

-

The open() method calls up an instance of DatabaseHelper, which is our local - implementation of the SQLiteOpenHelper class. It calls getWritableDatabase(), - which handles creating/opening a database for us.

-

close() just closes the database, releasing resources related to the - connection.

-

createNote() takes strings for the title and body of a new note, - then creates that note in the database. Assuming the new note is created successfully, the - method also returns the row _id value for the newly created note.

-

deleteNote() takes a rowId for a particular note, and deletes that note from - the database.

- -

fetchAllNotes() issues a query to return a {@link android.database.Cursor} over all notes in the - database. The query() call is worth examination and understanding. The first field is the - name of the database table to query (in this case DATABASE_TABLE is "notes"). - The next is the list of columns we want returned, in this case we want the _id, - title and body columns so these are specified in the String array. - The remaining fields are, in order: selection, - selectionArgs, groupBy, having and orderBy. - Having these all null means we want all data, need no grouping, and will take the default - order. See {@link android.database.sqlite.SQLiteDatabase SQLiteDatabase} for more details.

-

Note: A Cursor is returned rather than a collection of rows. This allows - Android to use resources efficiently -- instead of putting lots of data straight into memory - the cursor will retrieve and release data as it is needed, which is much more efficient for - tables with lots of rows.

- -

fetchNote() is similar to fetchAllNotes() but just gets one note - with the rowId we specify. It uses a slightly different version of the - {@link android.database.sqlite.SQLiteDatabase} query() method. - The first parameter (set true) indicates that we are interested - in one distinct result. The selection parameter (the fourth parameter) has been specified to search - only for the row "where _id =" the rowId we passed in. So we are returned a Cursor on - the one row.

-

And finally, updateNote() takes a rowId, title and body, and uses a - {@link android.content.ContentValues ContentValues} instance to update the note of the given - rowId.

- -

Step 3

- - - -

Open the notepad_list.xml file in res/layout -and - take a look at it. (You may have to - hit the xml tab, at the bottom, in order to view the XML markup.)

- -

This is a mostly-empty layout definition file. Here are some - things you should know about a layout file:

- - - - -

Step 4

-

We need to create the layout to hold our list. Add code inside - of the LinearLayout element so the whole file looks like this:

-
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-
-  <ListView android:id="@android:id/list"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-  <TextView android:id="@android:id/empty"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/no_notes"/>
-
-</LinearLayout>
-
- - -

Step 5

- - - -

To make the list of notes in the ListView, we also need to define a View for each row:

-
    -
  1. - Create a new file under res/layout called - notes_row.xml.
  2. -
  3. - Add the following contents (note: again the XML header is used, and the - first node defines the Android XML namespace)
    -
    -<?xml version="1.0" encoding="utf-8"?>
    -<TextView android:id="@+id/text1"
    -    xmlns:android="http://schemas.android.com/apk/res/android"
    -    android:layout_width="wrap_content"
    -    android:layout_height="wrap_content"/>
    -

    - This is the View that will be used for each notes title row — it has only - one text field in it.

    -

    In this case we create a new id called text1. The - + after the @ in the id string indicates that the id should - be automatically created as a resource if it does not already exist, so we are defining - text1 on the fly and then using it.

    -
  4. -
  5. Save the file.
  6. -
-

Open the R.java class in the - project and look at it, you should see new definitions for - notes_row and text1 (our new definitions) - meaning we can now gain access to these from the our code.

- -

Step 6

-

Next, open the Notepadv1 class in the source. In the following steps, we are going to - alter this class to become a list adapter and display our notes, and also - allow us to add new notes.

- -

Notepadv1 will inherit from a subclass - of Activity called a ListActivity, - which has extra functionality to accommodate the kinds of - things you might want to do with a list, for - example: displaying an arbitrary number of list items in rows on the screen, - moving through the list items, and allowing them to be selected.

- -

Take a look through the existing code in Notepadv1 class. - There is a currently an unused private field called mNoteNumber that - we will use to create numbered note titles.

-

There are also three override methods defined: - onCreate, onCreateOptionsMenu and - onOptionsItemSelected; we need to fill these - out:

- - -

Step 7

-

Change the inheritance of Notepadv1 from -Activity - to ListActivity:

-
public class Notepadv1 extends ListActivity
-

Note: you will have to import ListActivity into the -Notepadv1 - class using Eclipse, ctrl-shift-O on Windows or Linux, or - cmd-shift-O on the Mac (organize imports) will do this for you - after you've written the above change.

- -

Step 8

-

Fill out the body of the onCreate() method.

-

Here we will set the title for the Activity (shown at the top of the - screen), use the notepad_list layout we created in XML, - set up the NotesDbAdapter instance that will - access notes data, and populate the list with the available note - titles:

-
    -
  1. - In the onCreate method, call super.onCreate() with the - savedInstanceState parameter that's passed in.
  2. -
  3. - Call setContentView() and pass R.layout.notepad_list.
  4. -
  5. - At the top of the class, create a new private class field called mDbHelper of class - NotesDbAdapter. -
  6. -
  7. - Back in the onCreate method, construct a new -NotesDbAdapter - instance and assign it to the mDbHelper field (pass - this into the constructor for DBHelper) -
  8. -
  9. - Call the open() method on mDbHelper to open (or create) the - database. -
  10. -
  11. - Finally, call a new method fillData(), which will get the data and - populate the ListView using the helper — we haven't defined this method yet.
  12. -
-

- onCreate() should now look like this:

-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.notepad_list);
-        mDbHelper = new NotesDbAdapter(this);
-        mDbHelper.open();
-        fillData();
-    }
-

And be sure you have the mDbHelper field definition (right - under the mNoteNumber definition):

-
    private NotesDbAdapter mDbHelper;
- -

Step 9

- - - -

Fill out the body of the onCreateOptionsMenu() method.

- -

We will now create the "Add Item" button that can be accessed by pressing the menu -button on the device. We'll specify that it occupy the first position in the menu.

- -
    -
  1. - In strings.xml resource (under res/values), add - a new string named "menu_insert" with its value set to Add Item: -
    <string name="menu_insert">Add Item</string>
    -

    Then save the file and return to Notepadv1.

    -
  2. -
  3. Create a menu position constant at the top of the class: -
    public static final int INSERT_ID = Menu.FIRST;
    -
  4. -
  5. In the onCreateOptionsMenu() method, change the - super call so we capture the boolean return as result. We'll return this value at the end.
  6. -
  7. Then add the menu item with menu.add().
  8. -
-

The whole method should now look like this: -

-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        boolean result = super.onCreateOptionsMenu(menu);
-        menu.add(0, INSERT_ID, 0, R.string.menu_insert);
-        return result;
-    }
-

The arguments passed to add() indicate: a group identifier for this menu (none, - in this case), a unique ID (defined above), the order of the item (zero indicates no preference), - and the resource of the string to use for the item.

- -

Step 10

-

Fill out the body of the onOptionsItemSelected() method:

-

This is going - to handle our new "Add Note" menu item. When this is selected, the - onOptionsItemSelected() method will be called with the - item.getId() set to INSERT_ID (the constant we - used to identify the menu item). We can detect this, and take the - appropriate actions:

-
    -
  1. - The super.onOptionsItemSelected(item) method call goes at the - end of this method — we want to catch our events first!
  2. -
  3. - Write a switch statement on item.getItemId(). -

    In the case of INSERT_ID, call a new method, createNote(), - and return true, because we have handled this event and do not want to - propagate it through the system.

    -
  4. -
  5. Return the result of the superclass' onOptionsItemSelected() - method at the end.
  6. -
-

- The whole onOptionsItemSelect() method should now look like - this:

-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-        case INSERT_ID:
-            createNote();
-            return true;
-        }
-       
-        return super.onOptionsItemSelected(item);
-    }
- -

Step 11

-

Add a new createNote() method:

-

In this first version of - our application, createNote() is not going to be very useful. -We will simply - create a new note with a title assigned to it based on a counter ("Note 1", - "Note 2"...) and with an empty body. At present we have no way of editing - the contents of a note, so for now we will have to be content making one - with some default values:

-
    -
  1. Construct the name using "Note" and the counter we defined in the class: - String noteName = "Note " + mNoteNumber++
  2. -
  3. - Call mDbHelper.createNote() using noteName as the - title and "" for the body -
  4. -
  5. - Call fillData() to populate the list of notes (inefficient but - simple) — we'll create this method next.
  6. -
-

- The whole createNote() method should look like this:

-
-    private void createNote() {
-        String noteName = "Note " + mNoteNumber++;
-        mDbHelper.createNote(noteName, "");
-        fillData();
-    }
- - -

Step 12

- - -

Define the fillData() method:

-

This - method uses SimpleCursorAdapter, which takes a database Cursor - and binds it to fields provided in the layout. These fields define the row elements of our list - (in this case we use the text1 field in our - notes_row.xml layout), so this allows us to easily populate the list with - entries from our database.

-

To do this we have to provide a mapping from the title field in the returned Cursor, to - our text1 TextView, which is done by defining two arrays: the first a string array - with the list of columns to map from (just "title" in this case, from the constant - NotesDbAdapter.KEY_TITLE) and, the second, an int array - containing references to the views that we'll bind the data into - (the R.id.text1 TextView).

-

This is a bigger chunk of code, so let's first take a look at it:

- -
-    private void fillData() {
-        // Get all of the notes from the database and create the item list
-        Cursor c = mDbHelper.fetchAllNotes();
-        startManagingCursor(c);
-
-        String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
-        int[] to = new int[] { R.id.text1 };
-        
-        // Now create an array adapter and set it to display using our row
-        SimpleCursorAdapter notes =
-            new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
-        setListAdapter(notes);
-    }
- -

Here's what we've done:

-
    -
  1. - After obtaining the Cursor from mDbHelper.fetchAllNotes(), we - use an Activity method called - startManagingCursor() that allows Android to take care of the - Cursor lifecycle instead of us needing to worry about it. (We will cover the implications - of the lifecycle in exercise 3, but for now just know that this allows Android to do some - of our resource management work for us.)
  2. -
  3. - Then we create a string array in which we declare the column(s) we want - (just the title, in this case), and an int array that defines the View(s) - to which we'd like to bind the columns (these should be in order, respective to - the string array, but here we only have one for each).
  4. -
  5. - Next is the SimpleCursorAdapter instantiation. - Like many classes in Android, the SimpleCursorAdapter needs a Context in order to do its - work, so we pass in this for the context (since subclasses of Activity - implement Context). We pass the notes_row View we created as the receptacle - for the data, the Cursor we just created, and then our arrays.
  6. -
-

- In the future, remember that the mapping between the from columns and to resources - is done using the respective ordering of the two arrays. If we had more columns we wanted - to bind, and more Views to bind them in to, we would specify them in order, for example we - might use { NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY } and - { R.id.text1, R.id.text2 } to bind two fields into the row (and we would also need - to define text2 in the notes_row.xml, for the body text). This is how you can bind multiple fields - into a single row (and get a custom row layout as well).

-

- If you get compiler errors about classes not being found, ctrl-shift-O or - (cmd-shift-O on the mac) to organize imports. -

- -

Step 13

-

Run it! -

    -
  1. - Right click on the Notepadv1 project.
  2. -
  3. - From the popup menu, select Run As > - Android Application.
  4. -
  5. - If you see a dialog come up, select Android Launcher as the way of running - the application (you can also use the link near the top of the dialog to - set this as your default for the workspace; this is recommended as it will - stop the plugin from asking you this every time).
  6. -
  7. Add new notes by hitting the menu button and selecting Add - Item from the menu.
  8. -
- -

Solution and Next Steps

-

You can see the solution to this class in Notepadv1Solution -from -the zip file to compare with your own.

- -

Once you are ready, move on to Tutorial -Exercise 2 to add the ability to create, edit and delete notes.

- diff --git a/docs/html/training/notepad/notepad-ex2.jd b/docs/html/training/notepad/notepad-ex2.jd deleted file mode 100644 index 5ebd1aa966df4..0000000000000 --- a/docs/html/training/notepad/notepad-ex2.jd +++ /dev/null @@ -1,645 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Exercise 2 -parent.title=Notepad Tutorial -parent.link=index.html -@jd:body - - -

In this exercise, you will add a second Activity to your notepad application, to let the user -create and edit notes. You will also allow the user to delete existing notes through a context menu. -The new Activity assumes responsibility for creating new notes by -collecting user input and packing it into a return Bundle provided by the intent. This exercise -demonstrates:

- - -
- [Exercise 1] - - [Exercise 2] - - [Exercise 3] - [Extra Credit] -
- -

Step 1

- -

Create a new Android project using the sources from Notepadv2 under the -NotepadCodeLab folder, just like you did for the first exercise. If you see an error about -AndroidManifest.xml, or some problems related to an -android.zip file, right click on the project and select Android -Tools > Fix Project Properties.

- -

Open the Notepadv2 project and take a look around:

- - - -

Step 2

- - -

First, let's create the context menu that will allow users to delete individual notes. -Open the Notepadv2 class.

- -
    -
  1. In order for each list item in the ListView to register for the context menu, we call - registerForContextMenu() and pass it our ListView. So, at the very end of - the onCreate() method add this line: -
    registerForContextMenu(getListView());
    -

    Because our Activity extends the ListActivity class, getListView() will return us - the local ListView object for the Activity. Now, each list item in this ListView will activate the - context menu. -

  2. - Now fill in the onCreateContextMenu() method. This callback is similar to the other - menu callback used for the options menu. Here, we add just one line, which will add a menu item - to delete a note. Call menu.add() like so: -
    -public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    -    super.onCreateContextMenu(menu, v, menuInfo);
    -    menu.add(0, DELETE_ID, 0, R.string.menu_delete);
    -}
    -

    The onCreateContextMenu() callback passes some other information in addition to the Menu object, - such as the View that has been triggered for the menu and - an extra object that may contain additional information about the object selected. However, we don't care about - these here, because we only have one kind of object in the Activity that uses context menus. In the next - step, we'll handle the menu item selection.

    -
  3. -
- -

Step 3

-

Now that we've registered our ListView for a context menu and defined our context menu item, we need - to handle the callback when it is selected. For this, we need to identify the list ID of the - selected item, then delete it. So fill in the - onContextItemSelected() method like this:

-
-public boolean onContextItemSelected(MenuItem item) {
-    switch(item.getItemId()) {
-    case DELETE_ID:
-        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
-        mDbHelper.deleteNote(info.id);
-        fillData();
-        return true;
-    }
-    return super.onContextItemSelected(item);
-}
-

Here, we retrieve the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo} -with {@link android.view.MenuItem#getMenuInfo()}. The id field of this object tells us -the position of the item in the ListView. We then pass this to the deleteNote() -method of our NotesDbAdapter and the note is deleted. That's it for the context menu — notes -can now be deleted.

- -

Step 4

- - -

Fill in the body of the createNote() method: -

Create a new Intent to create a note - (ACTIVITY_CREATE) using the NoteEdit class. - Then fire the Intent using the startActivityForResult() method - call:

-
-Intent i = new Intent(this, NoteEdit.class);
-startActivityForResult(i, ACTIVITY_CREATE);
-

This form of the Intent call targets a specific class in our Activity, in this case - NoteEdit. Since the Intent class will need to communicate with the Android - operating system to route requests, we also have to provide a Context (this).

-

The startActivityForResult() method fires the Intent in a way that causes a method - in our Activity to be called when the new Activity is completed. The method in our Activity - that receives the callback is called - onActivityResult() and we will implement it in a later step. The other way - to call an Activity is using startActivity() but this is a "fire-and-forget" way - of calling it — in this manner, our Activity is not informed when the Activity is completed, and there is - no way to return result information from the called Activity with startActivity(). -

Don't worry about the fact that NoteEdit doesn't exist yet, - we will fix that soon.

- - - -

Step 5

- -

Fill in the body of the onListItemClick() override.

-

onListItemClick() is a callback method that we'll override. It is called when - the user selects an item from the list. It is passed four parameters: the - ListView object it was invoked from, the View - inside the ListView that was clicked on, the - position in the list that was clicked, and the - mRowId of the item that was clicked. In this instance we can - ignore the first two parameters (we only have one ListView it - could be), and we ignore the mRowId as well. All we are - interested in is the position that the user selected. We use - this to get the data from the correct row, and bundle it up to send to - the NoteEdit Activity.

-

In our implementation of the callback, the method creates an - Intent to edit the note using - the NoteEdit class. It then adds data into the extras Bundle of - the Intent, which will be passed to the called Activity. We use it - to pass in the title and body text, and the mRowId for the note we are - editing. Finally, it will fire the Intent using the - startActivityForResult() method call. Here's the code that - belongs in onListItemClick():

-
-super.onListItemClick(l, v, position, id);
-Cursor c = mNotesCursor;
-c.moveToPosition(position);
-Intent i = new Intent(this, NoteEdit.class);
-i.putExtra(NotesDbAdapter.KEY_ROWID, id);
-i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
-        c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
-i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
-        c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
-startActivityForResult(i, ACTIVITY_EDIT);
- -

Note: We assign the mNotesCursor field to a local variable at the - start of the method. This is done as an optimization of the Android code. Accessing a local - variable is much more efficient than accessing a field in the Dalvik VM, so by doing this - we make only one access to the field, and five accesses to the local variable, making the - routine much more efficient. It is recommended that you use this optimization when possible.

- - -

Step 6

- -

The above createNote() and onListItemClick() - methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill - in the body of the onActivityResult().

-

onActivityResult() is the overridden method - which will be called when an Activity returns with a result. (Remember, an Activity - will only return a result if launched with startActivityForResult.) The parameters provided - to the callback are:

- -

The combination of startActivityForResult() and - onActivityResult() can be thought of as an asynchronous RPC - (remote procedure call) and forms the recommended way for an Activity to invoke - another and share services.

-

Here's the code that belongs in your onActivityResult():

-
-super.onActivityResult(requestCode, resultCode, intent);
-Bundle extras = intent.getExtras();
-
-switch(requestCode) {
-case ACTIVITY_CREATE:
-    String title = extras.getString(NotesDbAdapter.KEY_TITLE);
-    String body = extras.getString(NotesDbAdapter.KEY_BODY);
-    mDbHelper.createNote(title, body);
-    fillData();
-    break;
-case ACTIVITY_EDIT:
-    Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
-    if (mRowId != null) {
-        String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
-        String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
-        mDbHelper.updateNote(mRowId, editTitle, editBody);
-    }
-    fillData();
-    break;
-}
- - - - -

Step 7

- - - -

Open the file note_edit.xml that has been provided and take a - look at it. This is the UI code for the Note Editor.

-

This is the most - sophisticated UI we have dealt with yet. The file is given to you to avoid - problems that may sneak in when typing the code. (The XML is very strict - about case sensitivity and structure, mistakes in these are the usual cause - of problems with layout.)

-

There is a new parameter used - here that we haven't seen before: android:layout_weight (in - this case set to use the value 1 in each case).

-

layout_weight is used in LinearLayouts - to assign "importance" to Views within the layout. All Views have a default - layout_weight of zero, meaning they take up only as much room - on the screen as they need to be displayed. Assigning a value higher than - zero will split up the rest of the available space in the parent View, according - to the value of each View's layout_weight and its ratio to the - overall layout_weight specified in the current layout for this - and other View elements.

-

To give an example: let's say we have a text label - and two text edit elements in a horizontal row. The label has no - layout_weight specified, so it takes up the minimum space - required to render. If the layout_weight of each of the two - text edit elements is set to 1, the remaining width in the parent layout will - be split equally between them (because we claim they are equally important). - If the first one has a layout_weight of 1 - and the second has a layout_weight of 2, then one third of the - remaining space will be given to the first, and two thirds to the - second (because we claim the second one is more important).

-

This layout also demonstrates how to nest multiple layouts - inside each other to achieve a more complex and pleasant layout. In this - example, a horizontal linear layout is nested inside the vertical one to - allow the title label and text field to be alongside each other, - horizontally.

- - -

Step 8

- -

Create a NoteEdit class that extends - android.app.Activity.

-

This is the first time we will have - created an Activity without the Android Eclipse plugin doing it for us. When - you do so, the onCreate() method is not automatically - overridden for you. It is hard to imagine an Activity that doesn't override - the onCreate() method, so this should be the first thing you do.

-
    -
  1. Right click on the com.android.demo.notepad2 package - in the Package Explorer, and select New > Class from the popup - menu.
  2. -
  3. Fill in NoteEdit for the Name: field in the - dialog.
  4. -
  5. In the Superclass: field, enter - android.app.Activity (you can also just type Activity and hit - Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code - assist and find the right package and class).
  6. -
  7. Click Finish.
  8. -
  9. In the resulting NoteEdit class, right click in the editor - window and select Source > Override/Implement Methods...
  10. -
  11. Scroll down through the checklist in the dialog until you see - onCreate(Bundle) — and check the box next to it.
  12. -
  13. Click OK.

    The method should now appear in your class.

  14. -
- -

Step 9

- -

Fill in the body of the onCreate() method for NoteEdit.

- -

This will set the title of our new Activity to say "Edit Note" (one - of the strings defined in strings.xml). It will also set the - content view to use our note_edit.xml layout file. We can then - grab handles to the title and body text edit views, and the confirm button, - so that our class can use them to set and get the note title and body, - and attach an event to the confirm button for when it is pressed by the - user.

-

We can then unbundle the values that were passed in to the Activity - with the extras Bundle attached to the calling Intent. We'll use them to pre-populate - the title and body text edit views so that the user can edit them. - Then we will grab and store the mRowId so we can keep - track of what note the user is editing.

- -
    -
  1. - Inside onCreate(), set up the layout:
    -
    setContentView(R.layout.note_edit);
    -
  2. -
  3. - Change the Activity title to the "Edit Note" string: -
    setTitle(R.string.edit_note);
    -
  4. -
  5. - Find the {@link android.widget.EditText} and {@link android.widget.Button} components we need: -

    These are found by the - IDs associated to them in the R class, and need to be cast to the right - type of View (EditText for the two text views, - and Button for the confirm button):

    -
    -mTitleText = (EditText) findViewById(R.id.title);
    -mBodyText = (EditText) findViewById(R.id.body);
    -Button confirmButton = (Button) findViewById(R.id.confirm);
    -

    Note that mTitleText and mBodyText are member - fields (you need to declare them at the top of the class definition).

    -
  6. -
  7. At the top of the class, declare a Long mRowId private field to store - the current mRowId being edited (if any). -
  8. -
  9. Continuing inside onCreate(), - add code to initialize the title, body and - mRowId from the extras Bundle in - the Intent (if it is present):
    -
    -mRowId = null;
    -Bundle extras = getIntent().getExtras();
    -if (extras != null) {
    -    String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    -    String body = extras.getString(NotesDbAdapter.KEY_BODY);
    -    mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    -
    -    if (title != null) {
    -        mTitleText.setText(title);
    -    }
    -    if (body != null) {
    -        mBodyText.setText(body);
    -    }
    -}
    - -
  10. -
  11. - Create an onClickListener() for the button: -

    Listeners can be one of the more confusing aspects of UI - implementation, but - what we are trying to achieve in this case is simple. We want an - onClick() method to be called when the user presses the - confirm button, and use that to do some work and return the values - of the edited note to the Intent caller. We do this using something called - an anonymous inner class. This is a bit confusing to look at unless you - have seen them before, but all you really need to take away from this is - that you can refer to this code in the future to see how to create a - listener and attach it to a button. (Listeners are a common idiom - in Java development, particularly for user interfaces.) Here's the empty listener:
    -

    -confirmButton.setOnClickListener(new View.OnClickListener() {
    -
    -    public void onClick(View view) {
    -
    -    }
    -
    -});
    -
  12. -
-

Step 10

- -

Fill in the body of the onClick() method of the OnClickListener created in the last step.

- -

This is the code that will be run when the user clicks on the - confirm button. We want this to grab the title and body text from the edit - text fields, and put them into the return Bundle so that they can be passed - back to the Activity that invoked this NoteEdit Activity. If the - operation is an edit rather than a create, we also want to put the - mRowId into the Bundle so that the - Notepadv2 class can save the changes back to the correct - note.

-
    -
  1. - Create a Bundle and put the title and body text into it using the - constants defined in Notepadv2 as keys:
    -
    -Bundle bundle = new Bundle();
    -
    -bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
    -bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
    -if (mRowId != null) {
    -    bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
    -}
    -
  2. -
  3. - Set the result information (the Bundle) in a new Intent and finish the Activity: -
    -Intent mIntent = new Intent();
    -mIntent.putExtras(bundle);
    -setResult(RESULT_OK, mIntent);
    -finish();
    - -
  4. -
-

The full onCreate() method (plus supporting class fields) should - now look like this:

-
-private EditText mTitleText;
-private EditText mBodyText;
-private Long mRowId;
-
-@Override
-protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.note_edit);
-
-    mTitleText = (EditText) findViewById(R.id.title);
-    mBodyText = (EditText) findViewById(R.id.body);
-
-    Button confirmButton = (Button) findViewById(R.id.confirm);
-
-    mRowId = null;
-    Bundle extras = getIntent().getExtras();
-    if (extras != null) {
-        String title = extras.getString(NotesDbAdapter.KEY_TITLE);
-        String body = extras.getString(NotesDbAdapter.KEY_BODY);
-        mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
-
-        if (title != null) {
-            mTitleText.setText(title);
-        }
-        if (body != null) {
-            mBodyText.setText(body);
-        }
-    }
-
-    confirmButton.setOnClickListener(new View.OnClickListener() {
-
-        public void onClick(View view) {
-            Bundle bundle = new Bundle();
-
-            bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
-            bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
-            if (mRowId != null) {
-                bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
-            }
-
-            Intent mIntent = new Intent();
-            mIntent.putExtras(bundle);
-            setResult(RESULT_OK, mIntent);
-            finish();
-        }
-    });
-}
- - - -

Step 11

- - - -

Finally, the new Activity has to be defined in the manifest file:

-

Before the new Activity can be seen by Android, it needs its own - Activity entry in the AndroidManifest.xml file. This is to let - the system know that it is there and can be called. We could also specify - which IntentFilters the activity implements here, but we are going to skip - this for now and just let Android know that the Activity is - defined.

-

There is a Manifest editor included in the Eclipse plugin that makes it much easier - to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly - or are not using the Eclipse plugin, see the box at the end for information on how to do this - without using the new Manifest editor.

-

    -
  1. Double click on the AndroidManifest.xml file in the package explorer to open it. -
  2. -
  3. Click the Application tab at the bottom of the Manifest editor.
  4. -
  5. Click Add... in the Application Nodes section. -

    If you see a dialog with radiobuttons at the top, select the top radio button: - "Create a new element at the top level, in Application".

  6. -
  7. Make sure "(A) Activity" is selected in the selection pane of the dialog, and click OK.
  8. -
  9. Click on the new "Activity" node, in the Application Nodes section, then - type .NoteEdit into the Name* - field to the right. Press Return/Enter.
  10. -
-

The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml - file, have a look around at some of the other options available (but be careful not to select - them otherwise they will be added to your Manifest). This editor should help you understand - and alter the AndroidManifest.xml file as you move on to more advanced Android applications.

- -

If you prefer to edit this file directly, simply open the - AndroidManifest.xml file and look at the source (use the - AndroidManifest.xml tab in the eclipse editor to see the source code directly). - Then edit the file as follows:
- <activity android:name=".NoteEdit" />

- This should be placed just below the line that reads:
- </activity> for the .Notepadv2 activity.

- -

Step 12

- -

Now Run it!

-

You should now be able to add real notes from -the menu, as well as delete an existing one. Notice that in order to delete, you must -first use the directional controls on the device to highlight the note. -Furthermore, selecting a note title from the list should bring up the note -editor to let you edit it. Press confirm when finished to save the changes -back to the database. - -

Solution and Next Steps

- -

You can see the solution to this exercise in Notepadv2Solution -from the zip file to compare with your own.

-

Now try editing a note, and then hitting the back button on the emulator -instead of the confirm button (the back button is below the menu button). You -will see an error come up. Clearly our application still has some problems. -Worse still, if you did make some changes and hit the back button, when you go -back into the notepad to look at the note you changed, you will find that all -your changes have been lost. In the next exercise we will fix these -problems.

- -

-Once you are ready, move on to Tutorial -Exercise 3 where you will fix the problems with the back button and lost -edits by introducing a proper life cycle into the NoteEdit Activity.

- - diff --git a/docs/html/training/notepad/notepad-ex3.jd b/docs/html/training/notepad/notepad-ex3.jd deleted file mode 100644 index 648f9f2d9bb74..0000000000000 --- a/docs/html/training/notepad/notepad-ex3.jd +++ /dev/null @@ -1,367 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Exercise 3 -parent.title=Notepad Tutorial -parent.link=index.html -@jd:body - - -

In this exercise, you will use life-cycle event callbacks to store and -retrieve application state data. This exercise demonstrates:

- - -
- [Exercise 1] - [Exercise 2] - - [Exercise 3] - - [Extra Credit] -
- -

Step 1

- -

Import Notepadv3 into Eclipse. If you see an error about -AndroidManifest.xml, or some problems related to an Android zip -file, right click on the project and select Android Tools > -Fix Project Properties from the popup menu. The starting point for this exercise is -exactly where we left off at the end of the Notepadv2.

-

The current application has some problems — hitting the back button when editing -causes a crash, and anything else that happens during editing will cause the -edits to be lost.

-

To fix this, we will move most of the functionality for creating and editing -the note into the NoteEdit class, and introduce a full life cycle for editing -notes.

- -
    -
  1. Remove the code in NoteEdit that parses the title and body - from the extras Bundle. -

    Instead, we are going to use the DBHelper class - to access the notes from the database directly. All we need passed into the - NoteEdit Activity is a mRowId (but only if we are editing, if creating we pass - nothing). Remove these lines:

    -
    -String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    -String body = extras.getString(NotesDbAdapter.KEY_BODY);
    -
  2. -
  3. We will also get rid of the properties that were being passed in - the extras Bundle, which we were using to set the title - and body text edit values in the UI. So delete: -
    -if (title != null) {
    -    mTitleText.setText(title);
    -}
    -if (body != null) {
    -    mBodyText.setText(body);
    -}
    -
  4. -
- -

Step 2

- -

Create a class field for a NotesDbAdapter at the top of the NoteEdit class:

-
    private NotesDbAdapter mDbHelper;
-

Also add an instance of NotesDbAdapter in the - onCreate() method (right below the super.onCreate() call):

-
-    mDbHelper = new NotesDbAdapter(this);
-    mDbHelper.open();
- -

Step 3

- -

In NoteEdit, we need to check the savedInstanceState for the -mRowId, in case the note - editing contains a saved state in the Bundle, which we should recover (this would happen - if our Activity lost focus and then restarted).

-
    -
  1. - Replace the code that currently initializes the mRowId:
    -
    -        mRowId = null;
    -
    -        Bundle extras = getIntent().getExtras();
    -        if (extras != null) {
    -            mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    -        }
    -        
    - with this: -
    -        mRowId = (savedInstanceState == null) ? null :
    -            (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
    -        if (mRowId == null) {
    -            Bundle extras = getIntent().getExtras();
    -            mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
    -                                    : null;
    -        }
    -        
    -
  2. -
  3. - Note the null check for savedInstanceState, and we still need to load up - mRowId from the extras Bundle if it is not - provided by the savedInstanceState. This is a ternary operator shorthand - to safely either use the value or null if it is not present. -
  4. -
  5. - Note the use of Bundle.getSerializable() instead of - Bundle.getLong(). The latter encoding returns a long primitive and - so can not be used to represent the case when mRowId is null. -
  6. -
- -

Step 4

- -

Next, we need to populate the fields based on the mRowId if we - have it:

-
populateFields();
-

This goes before the confirmButton.setOnClickListener() line. - We'll define this method in a moment.

- -

Step 5

- -

Get rid of the Bundle creation and Bundle value settings from the - onClick() handler method. The Activity no longer needs to - return any extra information to the caller. And because we no longer have - an Intent to return, we'll use the shorter version - of setResult():

-
-public void onClick(View view) {
-    setResult(RESULT_OK);
-    finish();
-}
-

We will take care of storing the updates or new notes in the database - ourselves, using the life-cycle methods.

- -

The whole onCreate() method should now look like this:

-
-super.onCreate(savedInstanceState);
-
-mDbHelper = new NotesDbAdapter(this);
-mDbHelper.open();
-
-setContentView(R.layout.note_edit);
-
-mTitleText = (EditText) findViewById(R.id.title);
-mBodyText = (EditText) findViewById(R.id.body);
-
-Button confirmButton = (Button) findViewById(R.id.confirm);
-
-mRowId = (savedInstanceState == null) ? null :
-    (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
-if (mRowId == null) {
-    Bundle extras = getIntent().getExtras();
-    mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
-                            : null;
-}
-
-populateFields();
-
-confirmButton.setOnClickListener(new View.OnClickListener() {
-
-    public void onClick(View view) {
-        setResult(RESULT_OK);
-        finish();
-    }
-
-});
- -

Step 6

- -

Define the populateFields() method.

-
-private void populateFields() {
-    if (mRowId != null) {
-        Cursor note = mDbHelper.fetchNote(mRowId);
-        startManagingCursor(note);
-        mTitleText.setText(note.getString(
-	            note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
-        mBodyText.setText(note.getString(
-                note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
-    }
-}
-

This method uses the NotesDbAdapter.fetchNote() method to find the right note to -edit, then it calls startManagingCursor() from the Activity class, which -is an Android convenience method provided to take care of the Cursor life-cycle. This will release -and re-create resources as dictated by the Activity life-cycle, so we don't need to worry about -doing that ourselves. After that, we just look up the title and body values from the Cursor -and populate the View elements with them.

- - -

Step 7

- - - -

Still in the NoteEdit class, we now override the methods - onSaveInstanceState(), onPause() and - onResume(). These are our life-cycle methods - (along with onCreate() which we already have).

- -

onSaveInstanceState() is called by Android if the - Activity is being stopped and may be killed before it is - resumed! This means it should store any state necessary to - re-initialize to the same condition when the Activity is restarted. It is - the counterpart to the onCreate() method, and in fact the - savedInstanceState Bundle passed in to onCreate() is the same - Bundle that you construct as outState in the - onSaveInstanceState() method.

- -

onPause() and onResume() are also - complimentary methods. onPause() is always called when the - Activity ends, even if we instigated that (with a finish() call for example). - We will use this to save the current note back to the database. Good - practice is to release any resources that can be released during an - onPause() as well, to take up less resources when in the - passive state. onResume() will call our populateFields() method - to read the note out of the database again and populate the fields.

- -

So, add some space after the populateFields() method - and add the following life-cycle methods:

-
    -
  1. - onSaveInstanceState(): -
    -    @Override
    -    protected void onSaveInstanceState(Bundle outState) {
    -        super.onSaveInstanceState(outState);
    -        saveState();
    -        outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
    -    }
    -

    We'll define saveState() next.

    -
  2. -
  3. - onPause(): -
    -    @Override
    -    protected void onPause() {
    -        super.onPause();
    -        saveState();
    -    }
    -
  4. -
  5. - onResume(): -
    -    @Override
    -    protected void onResume() {
    -        super.onResume();
    -        populateFields();
    -    }
    -
  6. -
-

Note that saveState() must be called in both onSaveInstanceState() -and onPause() to ensure that the data is saved. This is because there is no -guarantee that onSaveInstanceState() will be called and because when it is -called, it is called before onPause().

- - -

Step 8

- -

Define the saveState() method to put the data out to the -database.

-
-     private void saveState() {
-        String title = mTitleText.getText().toString();
-        String body = mBodyText.getText().toString();
-
-        if (mRowId == null) {
-            long id = mDbHelper.createNote(title, body);
-            if (id > 0) {
-                mRowId = id;
-            }
-        } else {
-            mDbHelper.updateNote(mRowId, title, body);
-        }
-    }
-

Note that we capture the return value from createNote() and if a valid row ID is - returned, we store it in the mRowId field so that we can update the note in future - rather than create a new one (which otherwise might happen if the life-cycle events are - triggered).

- - -

Step 9

- -

Now pull out the previous handling code from the - onActivityResult() method in the Notepadv3 - class.

-

All of the note retrieval and updating now happens within the - NoteEdit life cycle, so all the onActivityResult() - method needs to do is update its view of the data, no other work is - necessary. The resulting method should look like this:

-
-@Override
-protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
-    super.onActivityResult(requestCode, resultCode, intent);
-    fillData();
-}
- -

Because the other class now does the work, all this has to do is refresh - the data.

- -

Step 10

- -

Also remove the lines which set the title and body from the - onListItemClick() method (again they are no longer needed, - only the mRowId is):

-
-    Cursor c = mNotesCursor;
-    c.moveToPosition(position);
-
-and also remove: -
-
-    i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
-                    c.getColumnIndex(NotesDbAdapter.KEY_TITLE)));
-    i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
-                    c.getColumnIndex(NotesDbAdapter.KEY_BODY)));
-
-so that all that should be left in that method is: -
-
-    super.onListItemClick(l, v, position, id);
-    Intent i = new Intent(this, NoteEdit.class);
-    i.putExtra(NotesDbAdapter.KEY_ROWID, id);
-    startActivityForResult(i, ACTIVITY_EDIT);
- -

You can also now remove the mNotesCursor field from the class, and set it back to using - a local variable in the fillData() method: -

-    Cursor notesCursor = mDbHelper.fetchAllNotes();

-

Note that the m in mNotesCursor denotes a member field, so when we - make notesCursor a local variable, we drop the m. Remember to rename the - other occurrences of mNotesCursor in your fillData() method. - -

-Run it! (use Run As -> Android Application on the project right -click menu again)

- -

Solution and Next Steps

- -

You can see the solution to this exercise in Notepadv3Solution -from -the zip file to compare with your own.

-

-When you are ready, move on to the Tutorial -Extra Credit exercise, where you can use the Eclipse debugger to -examine the life-cycle events as they happen.

diff --git a/docs/html/training/notepad/notepad-extra-credit.jd b/docs/html/training/notepad/notepad-extra-credit.jd deleted file mode 100644 index 8ab20218788c5..0000000000000 --- a/docs/html/training/notepad/notepad-extra-credit.jd +++ /dev/null @@ -1,71 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Extra Credit -parent.title=Notepad Tutorial -parent.link=index.html -@jd:body - - -

In this exercise, you will use the debugger to look at the work you did -in Exercise 3. This exercise demonstrates:

- - -
- - [Exercise 1] - [Exercise 2] - [Exercise 3] - - [Extra Credit] - -
- -

Step 1

- -

Using the working Notepadv3, put breakpoints in the code at the - beginning of the onCreate(), onPause(), - onSaveInstanceState() and onResume() methods in the - NoteEdit class (if you are not familiar with Eclipse, just - right click in the narrow grey border on the left of the edit window at the - line you want a breakpoint, and select Toggle Breakpoint, you -should see a blue dot appear).

- -

Step 2

- -

Now start the notepad demo in debug mode:

- -
    -
  1. - Right click on the Notepadv3 project and from the Debug menu - select Debug As -> Android Application.
  2. -
  3. - The Android emulator should say "waiting for debugger to connect" - briefly and then run the application.
  4. -
  5. - If it gets stuck on the waiting... screen, quit the emulator and Eclipse, - from the command line do an adb kill-server, and then restart -Eclipse and try again.
- -

Step 3

- -

When you edit or create a new note you should see the breakpoints getting - hit and the execution stopping.

- -

Step 4

- -

Hit the Resume button to let execution continue (yellow rectangle with a -green triangle to its right in the Eclipse toolbars near the top).

- -

Step 5

- -

Experiment a bit with the confirm and back buttons, and try pressing Home and - making other mode changes. Watch what life-cycle events are generated and -when.

- -

The Android Eclipse plugin not only offers excellent debugging support for -your application development, but also superb profiling support. You can also -try using Traceview to profile your application. If your application is running too slow, this can help you -find the bottlenecks and fix them.

- diff --git a/docs/html/training/notepad/notepad-index.jd b/docs/html/training/notepad/notepad-index.jd deleted file mode 100644 index fde43fa7db268..0000000000000 --- a/docs/html/training/notepad/notepad-index.jd +++ /dev/null @@ -1,144 +0,0 @@ -excludeFromSuggestions=true -page.title=Notepad Tutorial -@jd:body - - -

The tutorial in this section gives you a "hands-on" introduction -to the Android framework and the tools you use to build applications on it. -Starting from a preconfigured project file, it guides you through the process of -developing a simple notepad application and provides concrete examples of how to -set up the project, develop the application logic and user interface, and then -compile and run the application.

- -

The tutorial presents the notepad application development as a set of -exercises (see below), each consisting of several steps. You can follow along -with the steps in each exercise and gradually build up and refine your -application. The exercises explain each step in detail and provide all the -sample code you need to complete the application.

- -

When you are finished with the tutorial, you will have created a functioning -Android application and learned in depth about many of the most important -concepts in Android development. If you want to add more complex features to -your application, you can examine the code in an alternative implementation -of a notepad application, in the -Sample Code documentation.

- - - -

Who Should Use this Tutorial

- -

This tutorial is designed for experienced developers, especially those with -knowledge of the Java programming language. If you haven't written Java -applications before, you can still use the tutorial, but you might need to work -at a slower pace.

- -

The tutorial assumes that you have some familiarity with the basic Android -application concepts and terminology. If you aren't yet familiar with those, you -should read Overview of an Android -Application before continuing.

- -

Also note that this tutorial uses -the Eclipse development environment, with the Android plugin installed. If you -are not using Eclipse, you can follow the exercises and build the application, -but you will need to determine how to accomplish the Eclipse-specific -steps in your environment.

- - -

Preparing for the Exercises

- -

This tutorial builds on the information provided in the Installing the SDK and Hello Android -documents, which explain in detail how to set up your development environment -for building Android applications. Before you start this tutorial, you should -read both these documents, have the SDK installed, and your work environment set up.

- -

To prepare for this lesson:

- -
    -
  1. Download the project - exercises archive (.zip)
  2. -
  3. Unpack the archive file to a suitable location on your machine
  4. -
  5. Open the NotepadCodeLab folder
  6. -
- -

Inside the NotepadCodeLab folder, you should see six project -files: Notepadv1, - Notepadv2, Notepadv3, - Notepadv1Solution, Notepadv2Solution - and Notepadv3Solution. The Notepadv# projects are -the starting points for each of the exercises, while the -Notepadv#Solution projects are the exercise - solutions. If you are having trouble with a particular exercise, you - can compare your current work against the exercise solution.

- - -

Exercises

- -

The table below lists the tutorial exercises and describes the development -areas that each covers. Each exercise assumes that you have completed any -previous exercises.

- - - - - - - - - - - - - - - - - - -
Exercise -1Start here. Construct a simple notes list that lets the user add new notes but not -edit them. Demonstrates the basics of ListActivity and creating -and handling - menu options. Uses a SQLite database to store the notes.
Exercise 2Add a second Activity to the -application. Demonstrates constructing a -new Activity, adding it to the Android manifest, passing data between the -activities, and using more advanced screen layout. Also shows how to -invoke another Activity to return a result, using -startActivityForResult().
Exercise 3Add handling of life-cycle events to -the application, to let it -maintain application state across the life cycle.
Extra -CreditDemonstrates how to use the Eclipse -debugger and how you can use it to -view life-cycle events as they are generated. This section is optional but -highly recommended.
- - - -

Other Resources and Further Learning

-