http://codezine.jp/article/detail/4842?p=4
前回までで「一覧」「参照」「登録」各画面の実装が一通り終了しました。
サンプルでは早々に次に進んでしまいますが、実はこの実装にはひとつ問題点があります。
「名刺一覧画面→新規→削除→OK」
と遷移するとエラーになります。
BizCardDao.delete()の実装はこのようになっています。
呼び出し側はこうです
このbizCard、新規登録だとIDが無いので、BizCardDao.deleteで例外が発生するのです。
ということでBizCardDaoを変更。
空のcatchをつけ加えただけです。
本来は削除する前にbizCard.getRowid().length()とかでチェックするのが正道なのだと思いますがまあいいや。
以上で新規登録→削除を行っても落ちないようになりました。
返り値がvoidなんで成功したんだか失敗したんだかわからないところがアレですが。
さて、これで大丈夫かと思いきやさらにさらに問題があります。
「名刺一覧画面→詳細→編集→削除→OK→保存」
今回は何処でエラーになっているかというと、ShowActivity.onActivityResult()です。
呼び出されるBizCardDao.load()
編集画面でbizCardを削除してしまっているので、bizCard.getRowid()に失敗してBizCardDao.load()中で例外が発生します。
/src/com.example.bizcard.db/BizCardDao.java
/src/com.example.bizcard/ShowActivity.java
まずBizCard.load()のほうは例外を単に空のcatchで括ります。
BizCard.load()の返り値は本来BizCard型ですが、取得に失敗した場合はnullが返るようになります。
ということで呼び出し側のShowActivity.onActivityResult()では返り値がnullだった場合さっさと名刺一覧画面に戻るようにしました。
以上で、「名刺一覧画面→詳細→編集→削除→OK→保存」とした場合、保存されたうえで名刺一覧画面に戻るようになりました。
これでめでたしめでたし、かと思えば実はまだ問題があったりして。
「名刺一覧画面→詳細→編集→削除→OK→戻るボタン」で、削除したはずの名刺情報が閲覧できます。
これはもまたShowActivity.onActivityResult()が原因です。
最初の一行でif( resultCode == RESULT_OK)とやっていますが、RegistActivity.onOptionsItemSelected()のように明示的に成功ステータスを返さないとここがtrueになりません。
戻るボタンが押された場合はRESULT_CANCELEDが返ってくるのでここのコードが実行されず、インテント呼び出し前の画面がそのまま表示されるという結果になります。
そこからさらに編集→保存などとしてみると「保存されました」とか表示するくせに一覧画面に戻ってさらに保存されていないというおかしな結果に。
解決策として、ここでは単純に返り値がどのようなステータスでもBizCardをリロードするようにします。
何故って、他に削除→戻るボタンと単純に戻るボタンを押しただけの状態を区別する方法が見つからないんじゃ。
/src/com.example.bizcard/ShowActivity.java
単にifを削除しただけです。
これで名刺一覧画面→詳細→編集→削除→OK→戻るボタンで、名刺一覧画面に戻るようになりました。
以上でようやくめでたしめでたしかと思えばまだまだ問題があったり。
「名刺一覧画面→新規登録→保存」、「名刺一覧画面→詳細→編集→削除→OK→保存」だと保存されたあと一覧画面に戻りますが、「名刺一覧画面→詳細→編集→保存」だと名刺詳細画面に移動します。
こんなふうに操作によってちがう挙動になるというのはよくないので、どの遷移を通っても名刺詳細画面に戻るべきでしょう。
問題は「名刺一覧画面→新規登録→保存」でShowActivity.bizCardにどうやって作成したBizCardオブジェクトを保存するかわかんないという点なわけですが。
PR
前回までで「一覧」「参照」「登録」各画面の実装が一通り終了しました。
サンプルでは早々に次に進んでしまいますが、実はこの実装にはひとつ問題点があります。
「名刺一覧画面→新規→削除→OK」
と遷移するとエラーになります。
BizCardDao.delete()の実装はこのようになっています。
1 | public void delete(BizCard bizCard) { |
2 | SQLiteDatabase db = helper.getWritableDatabase(); |
3 | try { |
4 | db.delete( BizCard.TABLE_NAME, BizCard.COLUMN_ID + "=?" , new String[]{ String.valueOf( bizCard.getRowid())}); |
5 | } finally { |
6 | db.close(); |
7 | } |
8 | } |
1 | BizCardDao dao = new BizCardDao( RegistActivity. this ); |
2 | dao.delete( bizCard); |
ということでBizCardDaoを変更。
1 | public void delete(BizCard bizCard) { |
2 | SQLiteDatabase db = helper.getWritableDatabase(); |
3 | try { |
4 | db.delete( BizCard.TABLE_NAME, BizCard.COLUMN_ID + "=?" , new String[]{ String.valueOf( bizCard.getRowid())}); |
5 | } catch (Exception e){ |
6 | } finally { |
7 | db.close(); |
8 | } |
9 | } |
本来は削除する前にbizCard.getRowid().length()とかでチェックするのが正道なのだと思いますがまあいいや。
以上で新規登録→削除を行っても落ちないようになりました。
返り値がvoidなんで成功したんだか失敗したんだかわからないところがアレですが。
さて、これで大丈夫かと思いきやさらにさらに問題があります。
「名刺一覧画面→詳細→編集→削除→OK→保存」
今回は何処でエラーになっているかというと、ShowActivity.onActivityResult()です。
1 | protected void onActivityResult( int requestCode, int resultCode, Intent data) { |
2 | if ( resultCode == RESULT_OK){ |
3 | // 表示を更新する |
4 | BizCardDao dao = new BizCardDao( this ); |
5 | bizCard = dao.load( bizCard.getRowid()); |
6 | updateView(); |
7 | } |
8 | } |
01 | public BizCard load(Long rowId) { |
02 | SQLiteDatabase db = helper.getReadableDatabase(); |
03 |
04 | BizCard bizCard = null ; |
05 | try { |
06 | Cursor cursor = db.query( BizCard.TABLE_NAME, null , BizCard.COLUMN_ID + "=?" , new String[]{ String.valueOf( rowId)}, null , null , null ); |
07 | cursor.moveToFirst(); |
08 | bizCard = getBizCard( cursor); |
09 | } finally { |
10 | db.close(); |
11 | } |
12 | return bizCard; |
13 | } |
/src/com.example.bizcard.db/BizCardDao.java
01 | public BizCard load(Long rowId) { |
02 | SQLiteDatabase db = helper.getReadableDatabase(); |
03 |
04 | BizCard bizCard = null ; |
05 | try { |
06 | Cursor cursor = db.query( BizCard.TABLE_NAME, null , BizCard.COLUMN_ID + "=?" , new String[]{ String.valueOf( rowId)}, null , null , null ); |
07 | cursor.moveToFirst(); |
08 | bizCard = getBizCard( cursor); |
09 | } catch (Exception e) { |
10 | } finally { |
11 | db.close(); |
12 | } |
13 | return bizCard; |
14 | } |
01 | protected void onActivityResult( int requestCode, int resultCode, Intent data) { |
02 | if ( resultCode == RESULT_OK){ |
03 | // 表示を更新する |
04 | BizCardDao dao = new BizCardDao( this ); |
05 | bizCard = dao.load( bizCard.getRowid()); |
06 | if (bizCard == null ){ |
07 | setResult( RESULT_CANCELED); |
08 | finish(); |
09 | return ; |
10 | } |
11 | updateView(); |
12 | } |
13 | } |
BizCard.load()の返り値は本来BizCard型ですが、取得に失敗した場合はnullが返るようになります。
ということで呼び出し側のShowActivity.onActivityResult()では返り値がnullだった場合さっさと名刺一覧画面に戻るようにしました。
以上で、「名刺一覧画面→詳細→編集→削除→OK→保存」とした場合、保存されたうえで名刺一覧画面に戻るようになりました。
これでめでたしめでたし、かと思えば実はまだ問題があったりして。
「名刺一覧画面→詳細→編集→削除→OK→戻るボタン」で、削除したはずの名刺情報が閲覧できます。
これはもまたShowActivity.onActivityResult()が原因です。
最初の一行でif( resultCode == RESULT_OK)とやっていますが、RegistActivity.onOptionsItemSelected()のように明示的に成功ステータスを返さないとここがtrueになりません。
戻るボタンが押された場合はRESULT_CANCELEDが返ってくるのでここのコードが実行されず、インテント呼び出し前の画面がそのまま表示されるという結果になります。
そこからさらに編集→保存などとしてみると「保存されました」とか表示するくせに一覧画面に戻ってさらに保存されていないというおかしな結果に。
解決策として、ここでは単純に返り値がどのようなステータスでもBizCardをリロードするようにします。
何故って、他に削除→戻るボタンと単純に戻るボタンを押しただけの状態を区別する方法が見つからないんじゃ。
/src/com.example.bizcard/ShowActivity.java
01 | protected void onActivityResult( int requestCode, int resultCode, Intent data) { |
02 | // 表示を更新する |
03 | BizCardDao dao = new BizCardDao( this ); |
04 | bizCard = dao.load( bizCard.getRowid()); |
05 | //取得できなければ一覧に戻る |
06 | if (bizCard == null ){ |
07 | setResult( RESULT_CANCELED); |
08 | finish(); |
09 | return ; |
10 | } |
11 | updateView(); |
12 | } |
これで名刺一覧画面→詳細→編集→削除→OK→戻るボタンで、名刺一覧画面に戻るようになりました。
以上でようやくめでたしめでたしかと思えばまだまだ問題があったり。
「名刺一覧画面→新規登録→保存」、「名刺一覧画面→詳細→編集→削除→OK→保存」だと保存されたあと一覧画面に戻りますが、「名刺一覧画面→詳細→編集→保存」だと名刺詳細画面に移動します。
こんなふうに操作によってちがう挙動になるというのはよくないので、どの遷移を通っても名刺詳細画面に戻るべきでしょう。
問題は「名刺一覧画面→新規登録→保存」でShowActivity.bizCardにどうやって作成したBizCardオブジェクトを保存するかわかんないという点なわけですが。
トラックバック
トラックバックURL: