En este tercer y último post del tutorial, vamos a practicar el ciclo de vida de la aplicación, y como guardar y recuperar el estado de la aplicación.
Puedes ver los anteriores artículos:
Tutorial Android paso a paso I: Desarrollo de la aplicación Notepad
Tutorial Android paso a paso II: Desarrollo de la aplicación Notepad
Objetivos:
• Conocer los eventos del ciclo de vida de la aplicación.
• Tecnicas para mantener el estado de la aplicación.
La aplicación actual contiene algunos problemas. Para solucionarlo, vamos a mover la funcionalidad de edición de notas a la clase NoteEdit.
1. Eliminar el siguiente código de la clase NoteEdit, que obtiene los datos de la nota a través del Bundle. Vamos a pasar a utilizar la clase DBHelper para obtener los datos directamente de la base de datos.
1 2 3 4 5 | Bundle extras = getIntent().getExtras(); … String title = extras.getString(NotesDbAdapter.KEY_TITLE); String body = extras.getString(NotesDbAdapter.KEY_BODY); mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID); |
2. Además, eliminamos la asignación de los datos a la interfaz de usuario
1 2 3 4 5 6 | if (title != null) { mTitleText.setText(title); } if (body != null) { mBodyText.setText(body); } |
Conectamos la clase NoteEdit con la base de datos.
1. Creamos un nuevo atributo:
1 | private NotesDbAdapter mDbHelper; |
2. Conectamos con la base de datos en el constructor, justo después de llamar al constructor padre:
1 2 | mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); |
Pasamos a comprobar el estado de la variable savedInstanceState. Esto sirve para comprobar si tenemos datos guardados en el Bundle, que debemos recuperar (Esto ocurre si la actividad pierde el foco y después se recupera).
1. Reeplazar el siguiente código:
1 2 3 4 5 | mRowId = null; Bundle extras = getIntent().getExtras(); if (extras != null) { mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID); } |
Por este otro
1 2 3 4 5 | mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID) : null; if (mRowId == null) { Bundle extras = getIntent().getExtras(); mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null; } |
Necesitamos completar los campos con los datos de la nota. Llamamos al método populateFields() que completaremos más adelante. Insertarlo justo antes de confirmButton.setOnClickListener():
1 | populateFields(); |
En esta actividad ya no es necesario devolver ningún tipo de datos, ya que vamos a guardar los datos directamente en esta actividad, por lo que es posible simplificar el método onClick() considerablemente:
1 2 3 4 | public void onClick(View view) { setResult(RESULT_OK); finish(); } |
Más adelante veremos como guardar los datos.
Definimos el método populateFields():
1 2 3 4 5 6 7 8 | 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))); } } |
Implementamos los métodos que gestionan el ciclo de vida de Android. Estos métodos nos permiten guardar y recuperar el estado de la actividad en caso de que esta se cierre o pase a un segundo plano (al recibir una llamada, por ejemplo):
1. onSaveInstanceState(): es llamada por Android cuando la actividad va a ser cerrada. Esto significa que aquí se debe guardar toda la información necesaria para restaurar la actividad en su estado anterior. Podemos pensar que es el método contrario a onCreate(), de hecho el Bundle que construimos en este método, es el que será pasado al método onCreate().
1 2 3 4 5 | @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId); } |
2. onPause(): es llamada cuando la actividad va a terminar (con finish()) o pasar a un segundo plano (con una llamada de teléfono).
1 2 3 4 5 | @Override protected void onPause() { super.onPause(); saveState(); } |
3. onResume(): es llamada al reactivar la actividad. Completamos los campos:
1 2 3 4 5 | @Override protected void onResume() { super.onResume(); populateFields(); } |
Para terminar de completar la clase NoteEdit, ya solo nos queda guardar los datos en la base de datos. Creamos el método saveState():
1 2 3 4 5 6 7 8 9 10 11 12 | 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); } } |
Volvemos a la clase Notepadv3. En el método onActivityResult(), teníamos implementado todo lo necesario para recibir los datos de la actividad y guardarla en la base de datos. Como este proceso ya lo realizamos en la clase NoteEdit, solo es necesario que actualizemos la lista con los nuevos datos:
1 2 3 4 5 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fillData(); } |
Finalmente, es esta misma clase, al seleccionar un elemento de la lista, ya no es ncesario pasar todos los datos de la nota, únicamente el id, por lo que el método onListItemClick(), quedaría de la siguiete manera:
1 2 3 4 5 6 7 | @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Intent i = new Intent(this, NoteEdit.class); i.putExtra(NotesDbAdapter.KEY_ROWID, id); startActivityForResult(i, ACTIVITY_EDIT); } |
Y con este último post hemos terminado el tutorial. Espero que os haya servido de ayuda y, como siempre, cualquier duda o pregunta en los comentarios.
Etiquetas: Android, aplicación, Desarrollo, notepad