そうだ、Android アプリを作ろう~準備編~2 MainActivityを観察する
前回の記事(そうだ、Android アプリを作ろう~準備編~いざログ取り大作戦)でひな型アプリのMainActivity.javaにログ出力処理を入れ、アプリを動かしながらログを取ってみた。今回はそのログからMainActivityのことをもっと知っていきたい。
ログから見えてきたもの
下の画像のようなひな型アプリには、メソッドが5つある。
それぞれのメソッドがいつコールされるかを確認したところ、以下のような結果になった。
onCreate() → アプリが起動したとき
onClick() → 画面右下のアイコンを押したとき
onCreateOptionsMenu() → アプリが起動したとき
onOptionsItemSelected() → 「Settings」を押したとき
onSupportNavigateUp() → コールされない……
少し補足を。
2のonClick() は画面右下の手紙アイコンを押したところ、以下のような表示になると共にコールされていた。
4のonOptionsItemSelected()は実際に触ってみないと分かりづらい。画面右上の3点リーダーのマークを押すとSettingsと書かれたメニューが表示され、それを押したときにコールされていた。
onSupportNavigateUp()はネットで調べてみて、どうやら戻るボタンと関係していそうだと分かったが、実際はコールされていないようなので、今回は無視しようと思う。時にはそんな切り捨ても必要だろう。
それを踏まえてソースコードを見てみる
「どんな操作をした時に、どんなメソッドがコールされるか」が分かれば、ソースコードの中身も意味を持ち始める。例えば、onCreate()とonClick()のソースコードは以下のようになっている。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate() call");
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Log.e(TAG, "onClick() call");
}
});
}
なるほど、確かにonClick()の中身には、表示されたダイアログと同じ文字列がある。onCreate()を理解するためには、まだもう少しお勉強が必要そうだが、アプリが起動する際にコールされているので、「あの見た目を成形するための処理なんだろうな~」と淡く理解することができる。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
Log.e(TAG, "onOptionsItemSelected() call");
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
onOptionsItemSelected()のソースコードは上記の通り。onOptionsItemSelected()は3点リーダーを押したときに現れるメニューを押したときにコールされていたので、メソッド名からそのメニューにあるアイテム=OptionsItemなのだなと推測してみる。いまはSettingsしかないけど、他にも追加できるんだろうな。
if文の中はSettingsを選択したときに通るのかも? 追加でログを入れて確認してみると、その予想は当たっていた。こんな風にプログラムが思い通りに動いていたとき、少しずつ理解が進んできた気がして少し嬉しくなる。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
Log.e(TAG, "onCreateOptionsMenu() call");
return true;
}
最後はonCreateOptionsMenu()。これに関しても、名前から3点リーダーを押したとき表示されるメニューに関係していそうと予想した。デベロッパーサイトを見てみると、この予想もヒットていて、あのメニューはOptionsMenuという名前で正解みたいだと分かった。このメソッドはそれを表示するための準備をしているようだ。
予想のヒットが連続するとカタルシスを味わえる。きっとこれがプログラミングが楽しい理由のひとつなんだろうな。
Activityのライフサイクル
ここまでくると、onXXXX()は何かイベントが発生するとコールされる者たちであることがなんとなく分かってくる。そして、Androidのアプリ開発を多少かじった人ならおそらく知っているであろう「Activityのライフサイクル」という概念をご紹介しておきたい。
とはいえ、この概念はデベロッパーサイトが意外にも(?)分かりやすく解説してくれているので、詳しい説明はそちらに譲りたい。ひとことで言うと、「アプリの状態が変わるときにコールされるメソッドがありますよ」ということ。今回登場したonCreate()もそれに含まれている。
たとえば、onPause()は他のアプリが表示され、自分のアプリが非表示となったときにコールされるので、そのタイミングで行いたい処理があれば、onPause()内に入れておけばOKという感じだ。今回のアプリのひな型にはonPause()がないため、そのような動きになった場合には特に何の処理もしていないことになる。
今回はActivityの動きを見てみた。次はFragmentに迫っていきたい。