6時間でわかるAndroid(Kotlin)開発入門

超ざっくり読んでみた。⇒Android Kotlin Fundamentals

感想

  • コルーチンの使いどころが初めて分かった気がする。
    • UIスレッドを止めずに非同期処理を実行して、そのままUIを更新できる。
  • アーキテクチャの実装はやはり難しそう。あとLiveData推しが凄い。
    • LiveData, Transformation, DataBinding周りはちゃんとやった方がよさげ。
  • モバイル開発特有のライブラリを全然知らない。Timber? Glide?聞いたこと無かった!
  • UI周りの説明が少なかったのは、Kotlinが関係ないからかもしれない。

目次

1. Build your first app

1.1 Get Started

  • build.gradle(Module:app)
  • app
  • res
  • AndroidManifest.xml

1.2 Basic Project

  • activity MainActivity and layout activity_main.xml
  • layout inflation setContentView()
  • View and ViewGroup
  • res/values/string.xml
  • findViewByID and R.id

1.3 Image and Compatibility

  • images goes to res/drawable folder
  • <ImageView> with src to "@drawable/image_name"
  • lateinit keyword promises the Kotlin compiler that the variable will be initialized before used.
  • tools namespace for design-time attributes. tools:src will display an image in AndroidStudio's preview only.
  • minSdkVersion, compileSdkVersion and targetSdkVersion
  • Android Jetpack
  • Vector drawables are supported higher from API level 21 (Android 5.0)

2. Layouts

2.1 LinearLayout

  • ViewGroup LinearLayout, ScrollView
  • style for font color, size, background color, padding, margin
  • res/values/styles.xml to reuse styles.
    <style name="NameStyle">
        <item name="android:textSize">@dimen/text_size</item>
    </style>
    

2.2 Interactivity

  • UIElement EditText and Buton
  • android:onClick
  • setOnClickListener(View.OnClickListener)

2.3 Constraint Layout

  • ViewGroup ConstraintLayout
  • position defined using at least one horizontal and vertical constraint
  • resposive layout
  • chain: group of views linked each other with bidirectional constraints
  • baseline constraint: align text with different font size.

2.4 Data Binding

  • add buildFeatures { dataBinding true } to gradle file.
  • use <layout> as root tag in xml file
  • add <data> block, define <variable> with a name and type.
  • refer to binding variable android:text="@={myBindingVar.value}"
  • use binding.myElement not findViewById<MyType>(R.id.my_element)
  •   <layout>
          <!-- DataBinding -->
          <data>
          <variable name="myBindingVar" type="com.example.myapp.MyType" />
          </data>
    
          <!-- Layout -->
          <LinearLayout>
          
          </LinearLayout>
      </layout>
    
    // define binding object
    private lateinit var binding: ActivityMainBinding
    
    // create binding variable
    private val myBindingVar: MyType = MyType(...)
    
    override fun onCreate(...) {
        ...
        // create binding object
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    
        // set binding variable
        binding.myBindingVar = myBindingVar
        ...
    }
    
    private fun onUserClick(view: View) {
        binding.apply {
            myBindingVar?.value = "updatingValue"
            invalidateAll()
        }
    }
    

3. Navigation

3.1 Fragment

  • <fragment> in activity_main.xml
  • res/layout/fragment_about.xml
  • inflate the layout in onCreateView (not onCreate)
  • activity.onCreate => activity.onAttachFragment => fragment.onCreate
  • fragment.onCreateView is called after activity.onCreate is finished.

3.2 Navigation

  • (not going too much about specific library)
  • setup Android navigation library
    • add navigation-fragment-ktx navigation-ui-ktx in build.gradle (module)
    • add ext variable in build.gradle (project)
  • res/navigation/navigation.xml
  • navigation host fragment is usually named NavHostFragment
  • findNavController().navigate()
  • can change back button behavior (default: most recent view)
  • supports up button to get back app's home
  • supports option menu
  • supports navigation drawer

3.3 Start external Activity

  • pass data from one fragment to another with SafeArgs (Gradle Plugin)
  • implicit intents
  • intents

4. LifeCycles of Activity and Fragments

4.1 LifeCycle and Logging

  • Create, Start, Pause, Restart, Resume, Stop, Destroy
  • Log.i
  • log library Timber

5. Architecture

5.1 ViewModel

  • UI controller handles UI and OS interactions
  • ViewModel stores and manages UI related data.
  • let data survive configuration changes such as screen rotations
  • Use ViewModel library

5.2 LiveData and LiveData observers

  • LiveData is an observable data holder that is lifecycle aware.
  • observers (activity, fragments) can get notified when data changes.
  • it only updates observers when the lifecycle state is STARTED or RESUMED
  • MutableLiveData

5.3 DataBinding with ViewModel + LiveData

5.4 LiveData transformations

  • Transformations.map() manipulates LiveData and return another LiveData

6. Database and Kotlin Coroutines

6.1 Room Database

  • Annotations
  • @Entity, @ColumnInfo, @Dao, @Insert, @Delete, @Update, @Query

6.2 Corountines

  • Corountines are asynchronous and non-blocking.
  • use suspend to make asynchronous code sequential.
    suspend fun asyncTask() {
        val req = buildReq()
        val res = sendReq(req)
        return parseResp(res)
    }
    
  • (similar to javascript's async keyword?)
  • when a coroutine calls a function marked suspend, it suspends execution until the result is ready
  • launch a corountine on main or UI thread, if the result affects the UI.
  • If the work does not affect UI, switch to the I/O context to use thread pool.

6.3 LiveData to control button states

7. RecyclerView

8. Internet

8.1 Get data from the internet

  • use Retrofit library to make http request for REST web service.
  • use Moshi library to parse JSON to Kotlin objects
  • android.permission.INTERNET

8.2(?) Load and display internet images

  • use Glide library to download, buffer, decode and cache images
  • BindingAdapters as an extension method: @BindingAdapter annotation

8.3(?) Filtering and Manipulate internet data

9. Repository (abstract data layer)

9.1 Repository

  • caching lets your app access data when the device is offline
  • The best way to store structure data on a device is to use local SQLite.
  • Repository class isolates data sources (Room, Web service) from the rest off the app.
  • Access to repository instead of fetching the data from the network
  • use database refresh strategy to insert and update data in local database.
  • To update the UI when database changes, use combination of LiveData and DAO.

9.2 WorkManager

  • WorkManager api: schedules to reliably run deferrable, asynchronous tasks.
  • usage: schedule a long running background task
  • components: Worker, WorkRequest, WorkManager
  • OneTimeWorkRequest and PeriodicWorkRequest
  • specify Constraints to check conditions (e.g. device is plugged in, Wi-Fi is connected)

10. Desiging for Everyone

10.1 Style and Themes

  • Themes, Styles and attributes
  • Style hierarchy
  • use downloadable font to keep apk size small

10.2 Material Design, dimesions and colors

  • floating action button
  • material design
  • theme and styles
  • colors
  • dimensions

10.3 Design for Everyone

  • RTL language
  • Accessibility Scanner
  • TalkBack with content descriptions
  • Chips: material design component
  • Dark theme
  • and more...