Kotlin协程+Flow+Retrofit实现网络请求
导包
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1"
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.0"
implementation "com.blankj:utilcode:1.12.5"
代码实现
interface NewsApi {
@GET("toutiao/index?key=5376aaa29d5cc66f87e664bb2b4a078b")
suspend fun getNewsBean(@Query("type") type:String): NewsBean
}
object NetworkService {
private val retrofit = Retrofit.Builder()
.client(
OkHttpClient.Builder()
.callTimeout(5, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}).build()
)
.baseUrl("http://v.juhe.cn/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val newsApi = retrofit.create<NewsApi>()
}
sealed class LatestNewsUiState {
data class Success(var news: NewsBean?) : LatestNewsUiState()
data class Error(var exception: Throwable?) : LatestNewsUiState()
}
class NewsViewModel: ViewModel() {
private val _uiState = MutableStateFlow<LatestNewsUiState>(LatestNewsUiState.Success(null))
val uiState: StateFlow<LatestNewsUiState> = _uiState
fun getNewData() {
viewModelScope.launch {
latestNews
.flowOn(Dispatchers.Default)
.catch { exception ->
_uiState.value = LatestNewsUiState.Error(exception)
}
.collect { favoriteNews ->
_uiState.value = LatestNewsUiState.Success(favoriteNews)
}
}
}
private val latestNews: Flow<NewsBean> = flow {
if (!NetworkUtils.isConnected()) throw RuntimeException("网络未连接")
val latestNews = NetworkService.newsApi.getNewsBean("top")
emit(latestNews)
}
}
class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<NewsViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycleScope.launch {
viewModel.uiState.collect { uiState ->
when (uiState) {
is LatestNewsUiState.Success -> result_tv.text = "result is ${uiState.news}"
is LatestNewsUiState.Error -> ToastUtils.showShort("error :${uiState.exception?.message}")
}
}
}
}
viewModel.getNewData()
}