環境設定
Retrofitを追加する
合わせてライブラリで必要になるJava8言語機能を追加する
Projectのbuild.gradleのリポジトリ確認
googleとjcenterがあること
buildscript {
….
repositories {
google()
jcenter()
}
….
}
appのbuild.gradleにライブラリを追加しJava8機能のサポート確認
android {
…
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
…
dependencies {
// Retrofit
implementation “com.squareup.retrofit2:retrofit:2.9.0”
implementation “com.squareup.retrofit2:converter-scalars:2.9.0”
}
権限の追加
manifests/AndroidManifest.xmlの タグの直前に以下を追加
<uses-permission android:name=”android.permission.INTERNET” />
インターネットからJSONデータを取得し表示するサンプル
xmlレイアウト
単一のフラグメント
データバインディングによりテキストビューを1つ表示
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/overviewFragment"
android:name="com.example.android.marsphotos.overview.OverviewFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_overview" />
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.android.marsphotos.overview.OverviewViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.marsphotos.overview.OverViewFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.status}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
アクティビティ
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
フラグメント
ViewModelを定義しデータバインディングする例
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.android.marsphotos.databinding.FragmentOverviewBinding
class OverviewFragment : Fragment() {
// OverviewViewModelを定義
private val viewModel: OverviewViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentOverviewBinding.inflate(inflater)
binding.lifecycleOwner = this
binding.viewModel = viewModel
return binding.root
}
}
ビューモデル
init処理にてインターネットに接続。
取得データをライブデータにセットする。
データの取得は、launchによりコルーチン(子スレッド)を起動してデータを取得している。
ネットワークエラーが発生する事があるのでエラー処理は必須
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.android.marsphotos.network.MarsApi
import kotlinx.coroutines.launch
class OverviewViewModel : ViewModel() {
// データバインディングのMutableLiveData変数を定義
private val _status = MutableLiveData<String>()
val status: LiveData<String> = _status
init {
// データ取得
getMarsPhotos()
}
// データ取得メソッド
private fun getMarsPhotos() {
try {
// launchによりコルーチン(スレッド)を起動してデータを取得する
viewModelScope.launch {
// Retrofitライブラリを使用したインターフェイスを利用
val listResult = MarsApi.retrofitService.getPhotos()
_status.value = listResult
}
} catch (e:Exception){
// エラー処理
_status.value = "Failure: ${e.message}"
}
}
}
ネットワークインターフェース
Retrofitビルダーの定義(レスポンスの戻りの型やベースURLなど)
Interfaceクラスの定義(エンドポイントと戻り型だけの関数1つ。
なぜこの関数でレスポンスが返されるのか仕組みが不明。。。)
オブジェクトの定義(Retrofitのオブジェクト。シングルトンオブジェクトとなり1つのみインスタンス化される)
import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.http.GET
// ベースアドレス
private const val BASE_URL = "https://android-kotlin-fun-mars-server.appspot.com"
// Retrofitビルダー(Stringを返すScalarsConverterFactoryでcreate)
private val retrofit = Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl(BASE_URL)
.build()
// interface
interface MarsApiService {
// getリクエストでphotosをエンドポイントと定義
@GET("photos")
// suspendとする事でコルーチンからの呼出しが可能
suspend fun getPhotos() : String
}
// シングルトンオブジェクトとして1つのみインスタンス化される
// retrofitServiceを遅延初期化(実際に利用される時に初期化)
object MarsApi {
val retrofitService : MarsApiService by lazy {
// RetrofitビルダーのcreateメソッドにMarsApiServiceインターフェイスを渡す
retrofit.create(MarsApiService::class.java)
}
}
トレーニング > KOTLIN を用いた ANDROID の基本 > インターネット > データを取得して表示する > インターネットからデータを取得する > 5. ウェブサービスと Retrofit