処理の流れ
状態:試行錯誤中
閲覧数:1,529
投稿日: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();
}
}