改造 2:在没有互联网的情况下阅读 JSON 时应用程序崩溃
Retrofit 2: App Crashes When Reading JSON Without Internet
我试图阻止我的应用程序在用户没有互联网连接时尝试使用 Gson 和 Retrofit2 读取 json 信息时崩溃。有什么想法吗?
我的代码:
片段
class ManuFragment : Fragment() {
private lateinit var viewModel: ManuFragmentVM
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentManuBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(ManuFragmentVM::class.java)
viewModel.apply {
manufacturer.observe(requireActivity(), {loadRecyclerView(it)})
setup()
}
}
查看模型
class ManuFragmentVM : ViewModel() {
val manufacturer = MutableLiveData<List<Manufacturers>>()
fun setup() {
viewModelScope.launch(Dispatchers.Default) {
manufacturer.postValue(CarsRepository().getAllManufacturers())
}
}
界面
interface ManufacturerApi {
@GET("url.json")
suspend fun fetchAllManufacturers(): List<Manufacturers>
}
存储库
class CarsRepository {
private fun manufacturerRetrofit(): ManufacturerApi {
return Retrofit.Builder()
.baseUrl("https://website.com/")
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
.build()
.create(ManufacturerApi::class.java)
}
suspend fun getAllManufacturers(): List<Manufacturers> {
return manufacturerRetrofit().fetchAllManufacturers()
}
看来您只需要将调用包装在 try-catch 中即可:
fun setup() {
viewModelScope.launch(Dispatchers.IO) {
try {
manufacturer.postValue(CarsRepository().getAllManufacturers())
} catch (ce: CancellationException) {
throw ce // Needed for coroutine scope cancellation
} catch (e: Exception) {
// display error
}
}
}
此外,您应该 运行 API 显式调用 IO 调度程序。您的其余代码看起来非常好。
您可以用 try catch
块包裹 manufacturer.postValue(CarsRepository().getAllManufacturers())
。如果您想告诉用户该错误,请创建另一个 LiveData 对象,例如val error: MutableLiveData<String>
和 post 来自 catch
块的错误文本。
我试图阻止我的应用程序在用户没有互联网连接时尝试使用 Gson 和 Retrofit2 读取 json 信息时崩溃。有什么想法吗?
我的代码:
片段
class ManuFragment : Fragment() {
private lateinit var viewModel: ManuFragmentVM
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentManuBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(ManuFragmentVM::class.java)
viewModel.apply {
manufacturer.observe(requireActivity(), {loadRecyclerView(it)})
setup()
}
}
查看模型
class ManuFragmentVM : ViewModel() {
val manufacturer = MutableLiveData<List<Manufacturers>>()
fun setup() {
viewModelScope.launch(Dispatchers.Default) {
manufacturer.postValue(CarsRepository().getAllManufacturers())
}
}
界面
interface ManufacturerApi {
@GET("url.json")
suspend fun fetchAllManufacturers(): List<Manufacturers>
}
存储库
class CarsRepository {
private fun manufacturerRetrofit(): ManufacturerApi {
return Retrofit.Builder()
.baseUrl("https://website.com/")
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
.build()
.create(ManufacturerApi::class.java)
}
suspend fun getAllManufacturers(): List<Manufacturers> {
return manufacturerRetrofit().fetchAllManufacturers()
}
看来您只需要将调用包装在 try-catch 中即可:
fun setup() {
viewModelScope.launch(Dispatchers.IO) {
try {
manufacturer.postValue(CarsRepository().getAllManufacturers())
} catch (ce: CancellationException) {
throw ce // Needed for coroutine scope cancellation
} catch (e: Exception) {
// display error
}
}
}
此外,您应该 运行 API 显式调用 IO 调度程序。您的其余代码看起来非常好。
您可以用 try catch
块包裹 manufacturer.postValue(CarsRepository().getAllManufacturers())
。如果您想告诉用户该错误,请创建另一个 LiveData 对象,例如val error: MutableLiveData<String>
和 post 来自 catch
块的错误文本。