如何在dagger 2模块中检查okhttp3的互联网连接

时间:2017-03-21 06:10:46

标签: android module dagger-2

我正在使用dagger 2为okhttp3创建模块。现在我想检查网络模块内的互联网连接。实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

查看任何answers to this canonical question并简单地封装它们。

例如,您可以使用如下界面:

public interface OnlineChecker {
    boolean isOnline();
}

然后最受欢迎的实施:

public class DefaultOnlineChecker implements OnlineChecker {

    private final ConnectivityManager connectivityManager;

    public DefaultOnlineChecker(ConnectivityManager connectivityManager) {
        this.connectivityManager = connectivityManager;
    }

    @Override
    public boolean isOnline() {
         NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
         return netInfo != null && netInfo.isConnectedOrConnecting();
    }
}

第二个最受欢迎的实施:

public class ExperimentalOnlineChecker implements OnlineChecker {

    private final Runtime runtime;

    public ExperimentalOnlineChecker(Runtime runtime) {
        this.runtime = runtime;
    }

    @Override
    public boolean isOnline() {
        try {
            Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
            int     exitValue = ipProcess.waitFor();
            return (exitValue == 0);
        }
        catch (IOException e)          { e.printStackTrace(); }
        catch (InterruptedException e) { e.printStackTrace(); }

        return false;
    }
}

然后在它自己的模块或其他地方绑定你想要的实现:

@Module
public class OnlineCheckerModule {

    @Provides
    public OnlineChecker onlineChecker() {
        Runtime runtime = Runtime.getRuntime();
        return new ExperimentalOnlineChecker(runtime);
    }
}

现在在您的Activity或Fragment中,您只需使用属性注入注入:

@Inject OnlineChecker onlineChecker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super(savedInstanceState);
    //perform injection with Dagger 2 and then you can use your
    //OnlineChecker
}

答案 1 :(得分:1)

对于遵循 MVVM Kotlin协程(非必要)且在 api 22 以上的用户,这里是:

使用 Dagger Android MVVM 的新实现。
在深入研究之前,您的匕首类图或对象图已经设置好,然后您必须执行以下操作:

ConnectivityInterceptor界面

interface ConnectivityInterceptor : Interceptor


ConnectivityInterceptorImpl

您可以使用Custom Exception类,也可以只使用 IOException
要检查移动设备的互联网连接状态,您必须使用连接管理器,当然还要从清单中启用网络状态
isOnline()中,有些东西已弃用了 api 28 api 29 ,如果api无法使用某些方法级别低于 22 ,因此我使用了当前状态,如果您高于api 22

,也不会打扰您
class ConnectivityInterceptorImpl (
    private var application: Application
) : ConnectivityInterceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        if (!isOnline())
            throw NoConnectivityException() //custom Exception class
        return chain.proceed(chain.request())
    }

    private fun isOnline(): Boolean {
        val connectivityManager = application.getSystemService(
            Context.CONNECTIVITY_SERVICE
        ) as ConnectivityManager
        var res = false
        connectivityManager.let {
            it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply {
                res = when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    else -> false
                }
            }
        }
        return res
    }
}



Dagger AppModule

匕首来了:
由于我们使用 Interceptor 来获取网络状态,因此当然会在 okHttpClient 中充当拦截器,并且在这里使用Okkhttp进行后面的网络调用retrofitBuilder(),这意味着我们正在执行名为 Singleton 的操作,因此在这种情况下,我们必须管理Dagger的对象图

@Module
abstract class AppModule {

    @Module
    companion object {
        @JvmStatic
        @Singleton
        @Provides
        fun providesConnectivityInterceptorImpl(application: Application):
                ConnectivityInterceptorImpl {
            return ConnectivityInterceptorImpl(application)
        }

        @JvmStatic
        @Singleton
        @Provides
        fun getClient(connectivityInterceptorImpl: ConnectivityInterceptorImpl): ApiService {
            val requestInterceptor = Interceptor { chain ->
                val url = chain.request()
                    .url()
                    .newBuilder()
                    .addQueryParameter("api", KEY)
                    .build()

                val request =
                    chain
                        .request()
                        .newBuilder()
                        .url(url)
                        .build()
                return@Interceptor chain.proceed(request)
            }

            val okHttpClient = OkHttpClient
                .Builder()
                .addInterceptor(connectivityInterceptorImpl) // here it is
                .addInterceptor(requestInterceptor)
                .connectTimeout(60, TimeUnit.SECONDS)
                .build()

            return Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService::class.java)
        }
    }
}



枚举类

处理网络状态

enum class Status  {
    RUNNING,
    SUCCESS,
    FAILED
}

class NetworkState(val status: Status, val msg: String) {
    companion object {
        val LOADED: NetworkState = NetworkState(Status.SUCCESS,"Success")
        val LOADING: NetworkState = NetworkState(Status.RUNNING,"Running")
        val ERROR: NetworkState = NetworkState(Status.FAILED,"Failed")
    }
}



存储库

在存储库中执行此操作:
如果您使用的是DataSource层,则可以在dataSource类中进行操作

private val _networkState = MutableLiveData<NetworkState>()
    val returnNetworkState: LiveData<NetworkState>
        get() = _networkState
fun networkData(){
CoroutineScope(IO).launch {
            _networkState.postValue(NetworkState.LOADING)
            try {
               //Asynchronous Operation
               _networkState.postValue(NetworkState.LOADED)

            } catch (e: NoConnectivityException) { // custom exception class
                Log.d(TAG, "No Internet Is Available")
               _networkState.postValue(NetworkState.ERROR)

            }
        }   
     }



在活动/片段内部,通过 LiveData 相应地更新您的UI。

myViewModel.returnNetworkState.observe(this, Observer {
          //textView or anything
        })


全部完成。