🚲

(初心者向け)Android開発のActivity, Fragment, Applicationとは

2023/04/05に公開

はじめに

Androidアプリ開発,していますか?
この記事ではAndroidアプリ開発のActivity, Fragment, Applicationクラスの概念について話します.
この記事は後輩に向けた勉強会用に作っています.

対象読者

  • AndroidでHelloWorldした人
  • Android開発でActivityしか書いたことない人

この記事で話すこと

  • Activity, Fragment, Applicationクラスの違いや特徴
  • MVVMをちょっと

この記事には無いもの

  • FragmentやApplicationクラスを使ったサンプルアプリ
  • 実装(implements)の基礎的な話.継承も.

目次

  1. Activity
  2. Fragment
  3. Application
  4. まとめ

出てくる用語

  • ライフサイクル
    • 画面ができた時,画面が一時停止した時,画面が破棄された時,みたいなタイミングを司る.
    • アクティビティのライフサイクルについて
    • 例えば「画面起動時にカメラを起動する」とか「画面終了時にデータを保存する」とかができます.

Activity 〜Androidアプリの基礎の基礎〜

Activityには以下の特徴があります.

  • Androidアプリの画面を表す
  • ライフサイクルがある
  • 複数個作れる(同時に表示できるわけではない)
  • 一画面に一個のみ
  • 常にActivityは1つ実行される(バックグラウンドで別のActivityが動く場合もある)

みなさん最初にAndroidアプリを作るときActivityから始まると思います.
ActivityにはライフサイクルとUIがあるので,これだけでアプリが作れます.

クラスの名前は〇〇Activityが基本です.
MainActivyty, HomeActivity, SettingActivity, SearchActivity...など.

MainActivity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
	
    }
}

しかしソースコードが大きくなればなるほど,Activityだけでは開発しにくくなってしまいます.
ソースコードが大きくなった時,一般的にはクラスを作ってActivityの処理を移動したりします.

しかし,それでは対応できない場合があります.
それを解決するのがFragmentとApplicationです.

Fragment 〜UI特化型クラス〜

Fragmentには以下の特徴があります.

  • Androidアプリの画面の一部を表す
  • ライフサイクルがある
  • 複数個作れる
  • 一画面に何個でも表示できる
  • ActivityかFragmentの上に存在する

つまりUIに特化したクラスです.
ActivityのUIの一部,もしくは全てをFragmentに変えられます.

File → New → Fragment → Fragment(Blank)でFragmentクラスを作ってみましょう.

MainFragment

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [MainFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class MainFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment MainFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            MainFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

色々あってわかりづらいですね.削りましょう.

MainFragment

class MainFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

}

最小構成です.
onCreateView では fragment_main.xml のレイアウトを展開しています.
ここで MainFragment ←→ fragment_main の紐付けをします.

xmlファイルの名前は 〇〇Fragment なら fragment_〇〇 になります(大文字小文字に注意)
名前が違っても inflater.inflate に登録すれば多分動くけど非推奨です.

ViewModel 〜Fragmentの大切なパートナー〜

FragmentはUIを司るクラスです.
つまりデータの処理をいっぱい書くのは不適切です.
そんな時に使うのがViewModelです.

MainViewModel.kt

class MainViewModel : ViewModel() {
    // TODO: Implement the ViewModel
}

これを使う場合,MVVMというアーキテクチャに沿った開発をおすすめします.
次の節でVMについても話します.

MVVMのさわり

Android開発のアーキテクチャにMVVMというのがあります.
Model View ViewModel で MVVMです.

Model: データやデータの取得、更新、処理
View: UIの表示や入力受付,トーストの発行もここ.
ViewModel: Viewの簡単な処理やModelとの接続をする.

カウントアプリを例に挙げます.
ボタンを押すとデータベースの数字が1上がり,その数字が画面に表示されます.
その時のそれぞれの仕事は
Fragment: View = ボタンを押した時イベントを呼ぶ,画面に数字を表示
ViewModel: ViewModel = データベースの数字を取って1足して保存する.Viewに数字を渡す
DataBase: Model = データベースから値を出し入れする

図にするとこんな感じです.

MVVMでアプリを開発している時のフォルダ構成の例は以下のようになります.

  • com.example
    • ui
      • main
        • MainFragment.kt(View)
        • MainViewModel.kt(ViewModel)
      • sub
        • SubFragment.kt(View)
        • SubViewModel.kt(ViewModel)
    • db
      • データベース操作クラス.kt(Model)
    • api
      • API操作クラス.kt(Model)
    • MainActivity.kt(View)
    • MainApplication.kt

今回はアーキテクチャの話をする場では無いのでこれ以上は割愛します.

Application 〜アプリの根幹にある基盤クラス〜

Applicationには以下の特徴があります.

  • Androidアプリ起動中ずっと存在する
  • ライフサイクルがない
  • 複数個作れない.一つだけ.
  • 全てのActivityからアクセスできる
  • Activityを経由してFragmentからもアクセスできる

Applicationクラスは事実上全てのクラスからアクセスできて,アプリ起動中はずっと存在し続けるクラスです.
超便利です.しかし,超便利だからこそ扱いには注意しなければなりません.
例えばMainActivity上のMainFragmentでしか扱わないデータをApplicationクラスに設置すると,他のActivityやFragmentで使わない時もずっと存在します.

しかし,複数個Activityがあり,それら全てで同じデータを扱うなら画面遷移時にintentでデータをやり取りするのではなく,Applicationのデータを見る様にすると楽に書けます.

使う時はManifest.xmlのapplicationにandroid:name="自分のApplicationクラスの名前"を書きましょう.

まとめ

ActivityとFramgentとApplicationの関係を図にすると以下の様になります.

  • Applicationはアプリ実行中,常に1つ存在する.
  • Activityは複数作れる.しかし1画面に1つだけ.
  • ActivityはApplicationにアクセスできる.
  • FragmentはActivityかFragmentの上にある.
  • Fragmentは使いまわせる.
  • FragmentはActivityを経由してApplicationにアクセスできる

しかし,実際Fragmentを使うとActivityに縦横100%のFragmentを設置して,ActivityからUIの処理をほぼ全てFragmentに移動します.
また,Activityも複数個作らず,1つだけになります.

そうなるとMVVMで書いたフォルダ構成が少しわかると思います.
この場合,2画面のアプリになります.

  • com.example
    • ui
      • main
        • MainFragment.kt(View)
        • MainViewModel.kt(ViewModel)
      • sub
        • SubFragment.kt(View)
        • SubViewModel.kt(ViewModel)
    • db
      • データベース操作クラス.kt(Model)
    • api
      • API操作クラス.kt(Model)
    • MainActivity.kt(View)
    • MainApplication.kt

おわりに

Android開発を始めてから,本でFragmentを,知人からの紹介でApplicationを知りました.
でも知らなければ調べられません.今回は名前だけでも覚えてください.それだけ知っていれば検索ができます.

最近ではJetPackComposeが流行っています.しかし,Fragment.xmlも直感的にレイアウトを作れるという点で便利です.

この記事で間違った内容がある場合,コメントもしくは何らかの連絡で教えていただければ修正します.

Discussion