処理の流れ
状態:試行錯誤中
閲覧数:1,571
投稿日:2013-10-16
更新日:2014-01-20
1.ActivityTopクラス
・onCreateメソッド → RecordItemクラスのインスタンスオブジェクトを生成
・onResumeメソッド → DataLoadTaskクラスのインスタンスオブジェクトを生成
2.DataLoadTaskクラス
・doInBackgroundメソッド → RecordDaoItemクラスのインスタンスオブジェクトを生成。同クラスのlist_search_itemメソッド実行
・onPostExecuteメソッド →
3.RecordDaoItemクラス
・RecordDaoItemコンストラクタ → DatabaseOpenHelperItemクラスのインスタンスオブジェクトを生成
・list_search_itemメソッド … 「ユーザー定義クラスRecordItemのオブジェクト」を格納するリストitemListを生成し、返す
4.DatabaseOpenHelperItemクラス
・概要超簡略化
・onCreateメソッド → RecordItemクラスのインスタンスオブジェクトを生成
・onResumeメソッド → DataLoadTaskクラスのインスタンスオブジェクトを生成
2.DataLoadTaskクラス
・doInBackgroundメソッド → RecordDaoItemクラスのインスタンスオブジェクトを生成。同クラスのlist_search_itemメソッド実行
・onPostExecuteメソッド →
3.RecordDaoItemクラス
・RecordDaoItemコンストラクタ → DatabaseOpenHelperItemクラスのインスタンスオブジェクトを生成
・list_search_itemメソッド … 「ユーザー定義クラスRecordItemのオブジェクト」を格納するリストitemListを生成し、返す
4.DatabaseOpenHelperItemクラス
・概要超簡略化
import android.style.systemdb.RecordItem; import android.style.systemdb.RecordDaoItem; |
public class ActivityTop extends Activity { public class DataLoadTask extends AsyncTask<Object, Integer, List<RecordItem>> { //インナークラス protected List<RecordItem> doInBackground(Object... params) { RecordDaoItem dao = new RecordDaoItem(ActivityTop. this ); |
1.ActivityTopクラス
インポート
▼/DbDiary/src/android/style/system/ActivityTop.java
import java.util.Calendar; import android.style.systemdb.RecordItem; |
プロパティ
public class ActivityTop extends Activity { private RecordItem Record = null ;
// 操作したいアイテムのプロパティを宣言/ private TextView tv_last = null ; // 先月 private TextView tv_date = null ; // 年月 private TextView tv_next = null ; // 翌月 private EditText et_search = null ; // 検索窓 private Button btn_top_search = null ; // 検索ボタン private Button btn_top_add = null ; // 今日の日記を書くボタン final Calendar calendar = Calendar.getInstance(); //インポートしているCalendarクラスのオブジェクトcalendarを生成 int year = calendar.get(Calendar.YEAR); //現在の年を取得 int month = calendar.get(Calendar.MONTH) + 1 ; //現在の月を取得。+1する理由はCalendarクラスの月だけ1~12ではなく0~11で表されるため final int day = calendar.get(Calendar.DAY_OF_MONTH); //現在の月の何日目かを取得
private LinearLayout all = null ; // ViewGroupクラス boolean isWordSearch = false ; //DataLoadTaskクラス … doInBackgroundメソッドで、RecordDaoItemクラスlist_search_itemメソッドを呼ぶ際、第2引数で渡す // Toast制御 private Handler stopToastHandler = new Handler(); private Toast g_Toast = null ; private boolean toastFlag = true ; |
onCreate()
RecordItemクラスのインスタンスオブジェクトを生成
・アクティビティへビューを追加。予めXMLファイルで作成している配置ビュー読込、表示領域を確保
・この時点でのデータは空
@Override protected void onCreate(Bundle savedInstanceState) { //引数としてBundleクラスのオブジェクトを受け取る(このアクティビティの 以前の状態が保存されていた場合、このメソッドにはその状態を保持している Bundleオブジェクトが引数として渡される) super .onCreate(savedInstanceState); //superキーワードを使って、スーパークラスであるActivityオブジェクトのonCreateメソッドを呼び出し、 「onCreate」メソッドをオーバーライド setContentView(R.layout.top); //アクティビティにビューを追加。配置ビューをXMLファイルで作成しておき、それを読み込んで利用。レイアウト用XMLファイル名が「○○.xml」だった場合には、「R.layout.○○」で参照可能。ここでは、「R.layout.top」で「top.xml」を読込 // どのアイテムを操作するかリソースを割り当て // findViewById … 引数にリソースIDを指定すると、対応するViewオブジェクトを返す(返り値として対応するViewオブジェクトを受け取るので、いきなり利用可能。オブジェクト生成する必要はない) // 「ビューに対して割り当てられたリソースID」から、対応するビューオブジェクトを取得(リソースIDから、GUIオブジェクトを取得) tv_last = (TextView)findViewById(R.id.TextView_last_month); //引数にて別途XMLファイルで作成したレイアウトを表すIDを指定。先月 tv_date = (TextView)findViewById(R.id.TextView_date); //2013/9 tv_next = (TextView)findViewById(R.id.TextView_next_month); //翌月 et_search = (EditText)findViewById(R.id.EditText_top_search); //編集 btn_top_search = (Button)findViewById(R.id.Button_top_search); //検索 btn_top_add = (Button)findViewById(R.id.Button_top_add); //今日の日記を書く all = (LinearLayout)findViewById(R.id.LinearLayout_all); //画面全体LinearLayout // ボタンやエディットテキストの初期化 et_search.setFocusable( false ); btn_top_search.setEnabled( false ); // Recordの日付データを初期化 Record = new RecordItem(); Record.setItemSearchNen(String.valueOf(year)); Record.setItemSearchTuki(String.valueOf(month)); // 起動時の1発目は日付で一覧を取得する為、falseに設定 isWordSearch = false ; } |
・Stringクラスで用意されているvalueOfメソッドを使って文字列に変換
※valueOfメソッドは引数に指定された値の文字列表現を返す
→RecordItemクラスのプライベートプロパティ「itemsearchnen」「itemsearchtuki」へ、セッターを通じてデータ格納
onResume()
DataLoadTaskクラスのインスタンスオブジェクトを生成
・DataLoadTaskクラス呼出、実行
/** * アクティビティが前面に来るたびに一覧を更新 */ @Override protected void onResume() { super .onResume();
// 一覧取得タスクの実行 DataLoadTask task = new DataLoadTask(); //作成したクラスのインスタンスを作る task.execute(); //起動 } |
DataLoadTaskクラスの概要
概要
ActivityTopクラスのネストクラス
▼/DbDiary/src/android/style/system/ActivityTop.java
AsyncTaskクラスを継承してバックグラウンド処理
・データベースへアクセスする際、利用
・具体的には、バックグラウンドで一覧データの取得と表示を行う
・仕組みとしては、AsyncTaskを継承して非同期に動作を行う
・比較的重たい処理となる「データベース問い合わせ、一覧データ取得・表示」は、メインスレッド(UI thread)に負荷を与えずに行うため、AsyncTaskクラスを継承した「DataLoadTask」クラスで実施
実型引数
クラス宣言時のGenerics実型第1引数
・execute()メソッド引数からdoInBackgroundメソッド引数()へ渡す型を指定
・ここでは「task.execute()」で渡されていないので関係ない
・具体的には、execute()を引数なしで呼んでいるため、doInBackground()には引数が渡らない
・つまり、params.lengthは0
クラス宣言時のGenerics実型第3引数
・処理結果の型
・具体的にはdoInBackgroundの返り値
・ここでは「List<RecordItem>」型を指定(=java.util.List<android.style.systemdb.RecordItem>;)
・可変長引数
・可変長引数が「nullの場合」と「なかった場合」で条件分け
・メソッド(Object... params)
・execute()およびdoInBackground()の引数の型を、AsyncTaskを継承したクラスの作成時に指定可能
/** * 一覧データの取得と表示を行うタスク */ public class DataLoadTask extends AsyncTask<Object, Integer, List<RecordItem>> { // <java.lang.Object,java.lang.Integer,java.util.List<android.style.systemdb.RecordItem>
/*バックグラウンドで実行させたい処理*/ @Override protected List<RecordItem> doInBackground(Object... params) {
/* 一覧を呼び出し */ RecordDaoItem dao = new RecordDaoItem(ActivityTop. this );
return dao.list_search_item( Record ,isWordSearch ); // 第1引数はRecordItemクラスインスタンス。初回は初期化されたRecordの日付データ。第2引数の初回はfalse }
} |
Generics実型第3引数で指定したList<RecordItem>とは何か?
・引数として渡されていないのに指定できる理由は、「import android.style.systemdb.RecordItem;」
・その実体はレコード情報クラス
・つまり、List<RecordItem>は、その要素が全てRecordItemクラス型である(RecordItemクラスのインスタンス、RecordItemサブクラスのインスタンス、null)ことが保証されているList
Generics実型第3引数で、「List<RecordItem>」を指定できる理由
・Listインターフェイスインポート
import java.util.List; |
・RecordItemインポート
※ユーザ定義クラスのため、「ユーザ作成パッケージ名」を付与
import android.style.systemdb.RecordItem; |
2.DataLoadTaskクラス … メソッド
onPreExecute()
タスク開始直後に呼ばれる
・何か初期化したいことがあればここへ記述
・ここではプログレスダイアログを初期化して表示
// タスク開始直後に呼ばれる // 何か初期化したいことがあればここへ記述 // ここではプログレスダイアログを初期化して表示 @Override protected void onPreExecute() { // 処理中ダイアログ表示 progressDialog = new ProgressDialog(ActivityTop. this ); progressDialog.setMessage(getResources().getText(R.string.loading)); progressDialog.setIndeterminate( true ); progressDialog.show(); } |
doInBackground()
バックグラウンドで実行させたい処理
・インナークラス内にて、「RecordDaoItemクラスのインスタンスオブジェクト」を生成し、その際引数として「DataLoadTaskクラスのインスタンスオブジェクト」を渡す
//バックグラウンドで実行させたい処理 @Override protected List<RecordItem> doInBackground(Object... params) { // 一覧を呼び出し RecordDaoItem dao = new RecordDaoItem(ActivityTop. this ); |
インナークラスは、「.」でつないで表記
・ActivityTopクラスの中に新しくDataLoadTaskクラスを定義しているため、DataLoadTaskはActivityTopクラスのインナークラス
・そのため、DataLoadTaskクラスは、ActivityTop.DataLoadTask と「.」でつないで表記
「引数の数」はクラスに依存
・最後の行は、自分自身をパラメータとして「クラス名」のオブジェクトを生成しているため、「引数の数」はそのクラスによる
・具体的には、RecordDaoItemに依存
・下記コンストラクタにより、「引数の数」は1
/** * データアクセスクラス */ public class RecordDaoItem {
private DatabaseOpenHelperItem helper = null ; public RecordDaoItem(Context context) { |
※引数リストの一般的な形式 … 型 変数1, 型 変数2,
このときのActivityTop.thisとは?
・「ActivityTop.DataLoadTaskクラス」のオブジェクト自身を意味する
・オブジェクト自身とは、例えば「tmp = new ActivityTop.DataLoadTask();」とした場合は tmp に該当
・ここでは「ActivityTop」クラスのインナークラス「DataLoadTask」にて「RecordDaoItem dao = new RecordDaoItem(ActivityTop.this);」しているので、「DataLoadTask」クラスのインスタンスオベジェクトとなる
「ActivityTop.this」ではなく、単なる「this」だと、どうなる?
エラー発生
コンストラクター RecordDaoItem(ActivityTop.DataLoadTask) は未定義です
・DataLoadTaskの中では、thisはクラスオブジェクト自身を指す・一方、「new RecordDaoItem」引数には、「Context context」つまり Activityを継承したActivityTopクラスのオブジェクトを指定する必要がある
・つまり、インナークラス内から「外部クラスのthis」を参照したい
・そのためには、「外部クラス名 + .this」と表記することが絶対条件となる
※DataLoadTaskクラスは、外側のActivityTopクラスのインスタンスに内側からアクセスしている
RecordDaoItemクラス呼出
import android.style.systemdb.RecordItem; import android.style.systemdb.RecordDaoItem; |
// 一覧データの取得と表示を行うタスク public class DataLoadTask extends AsyncTask<Object, Integer, List<RecordItem>> { private ProgressDialog progressDialog = null ; // バックグラウンドで実行させたい処理 @Override protected List<RecordItem> doInBackground(Object... params) { // 一覧を呼び出し RecordDaoItem dao = new RecordDaoItem(ActivityTop. this ); |
doInBackground() → 3.RecordDaoItemクラス
コンストラクタ
RecordDaoItemクラスのコンストラクタへ引数を渡す
・ここでは、DataLoadTaskクラスのインスタンスオブジェクトが渡される
▼/src/android/style/systemdb/RecordDaoItem.java
・RecordDaoItemクラスのコンストラクタは、「DataLoadTaskクラスのインスタンスオブジェクト」を受け取る
/** * データアクセスクラス */ public class RecordDaoItem {
private DatabaseOpenHelperItem helper = null ; public RecordDaoItem(Context context) { //DataLoadTaskクラスのインスタンスオブジェクト |
・RecordDaoItemクラスのコンストラクタは、受け取った「DataLoadTaskクラスのインスタンスオブジェクト」を引数として、新たに「DatabaseOpenHelperItem」クラスのインスタンスオブジェクトを生成
public RecordDaoItem(Context context) { helper = new DatabaseOpenHelperItem(context); } |
doInBackground() → 3.RecordDaoItemクラス → 4.DatabaseOpenHelperItemクラス
・初回アクセス(データベース作成)した時だけonCreateメソッドが呼ばれ、テーブル作成
/** * データベース生成 * onCreateが動作するのは初回アクセス(データベース作成)した時だけ * コード的には、コンストラクタに渡されたDBファイル名が存在しない場合に呼ばれる */ @Override public void onCreate(SQLiteDatabase db) { db.beginTransaction(); try { StringBuilder createSql = new StringBuilder(); createSql.append( "create table " + RecordItem.TABLE_NAME_ITEM + " (" ); createSql.append(RecordItem.COLUMN_ID + " integer primary key autoincrement not null, " ); createSql.append(RecordItem.COLUMN_ITEMNIKKI + " text, " ); createSql.append(RecordItem.COLUMN_ITEMNEN + " text, " ); createSql.append(RecordItem.COLUMN_ITEMTUKI + " text, " ); createSql.append(RecordItem.COLUMN_ITEMHI + " text" ); createSql.append( ")" ); db.execSQL( createSql.toString()); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } |