在Retrofit2获取请求期间没有互联网时,应用程序崩溃

时间:2019-12-04 04:25:32

标签: android kotlin get retrofit2

当我尝试向服务器发出Get请求并且没有互联网时,我的应用程序似乎一直崩溃,给我一个E/AndroidRuntime: FATAL EXCEPTION: main错误。我希望该应用程序能够运行,但不会显示任何数据。

Log.i("getStoreData()" , "Inside the coroutine before getData")

这是我在应用程序崩溃前打印的最后一条日志。

 private fun getStoreData() {

        Log.i("getStoreData()", " inside getStoreData")

        val job = coroutineScope.launch {
            Log.i("getStoreData()" , "Inside the coroutine before getData")
            var data = StoreAPI.retrofitService.getData()
            Log.i("getStoreData()" , "Inside the coroutine after getData")
            try {
                var storeData = data.stores

                _status.value = "Success: ${storeData.size} Stores received"

                if(storeData.size > 0){
                    _stores.value = storeData
                }
            } catch (t: Throwable) {

                Log.i("Retrofit catch block", _status.value)
                _status.value = "Failure: " + t.message

                t.printStackTrace()
            }
        }


    }

StoreAPIService.kt

private const val URL = "http://sandbox.bottlerocketapps.com/BR_Android_CodingExam_2015_Server/"


private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()

private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .baseUrl(URL)
    .build()

interface StoreAPIService{

    //Initially was using Jake Wharton's library for retrofit2 kotlin coroutines support but it has been deprecated since the support
    // addition of the suspend keyword in retrofit 2.6.0
    //Suspend does all the task of coroutines for us by just adding it before the function declaration
    @GET("stores.json")
    suspend fun getData():
            Data //return Data object because Data has access to the Store JSON Object/Array
}

object StoreAPI{
    val retrofitService: StoreAPIService by lazy {
        retrofit.create(StoreAPIService::class.java)
    }
}

enter image description here

知道为什么吗?

编辑:

我无法使用这些网络连接功能,因为我的片段未连接到任何活动,并且片段已连接到viewModel。因此,此代码行不起作用,因为没有上下文可将其绑定到。如果您有解决办法,那也很好。

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

5 个答案:

答案 0 :(得分:0)

您需要在致电改造服务之前添加Internet检查,因为要从服务器获取一些数据,必须具有Internet连接

答案 1 :(得分:0)

此方法检查手机是否已连接到互联网并返回true
如果已连接:

private boolean isNetworkConnected() {
     ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
}

清单中

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

编辑:此方法实际上检查设备是否已连接到互联网(有
     它可能连接到网络,但没有连接到互联网)。

public boolean isInternetAvailable() {
    try {
          InetAddress ipAddr = InetAddress.getByName("google.com"); 
          //You can replace it with your name
          return !ipAddr.equals("");

     }catch (Exception e) {
          return false;
     }
}

答案 2 :(得分:0)

这将告诉您是否已连接到网络:

boolean connected = false;
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED || 
            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) {
        //we are connected to a network
        connected = true;
    }
    else
        connected = false;

答案 3 :(得分:0)

我也遵循了该教程,但是我不记得它具有离线模式。这是您必须自己整合的一种选择。

创建viewModel时,由于它具有init块,因此会调用API,如果没有Internet连接,则会崩溃。

因此,您应该向ini​​t viewModel编写一些代码,以检查您是否具有Internet连接。或在进行API调用以获取数据的方法中。

在该教程的下一课“幕后”中,他们讨论了脱机模式。

答案 4 :(得分:0)

注意:在拨打任何网络电话或发送任何请求之前,您必须确保设备已连接到互联网。我引诱您编写一个简单的函数来检查您是否已连接,如果已连接,则您可以发送请求或进行网络调用。