如何在改造android

时间:2017-08-13 07:57:03

标签: android retrofit okhttp dagger-2

  1. 我已经定义了以下类。
  2. 我在这里使用了Dagger和Retrofit
  3. 我想做什么 ::

    我正在尝试抓住下面请求中的OfflineException如何正确地在主要活动中捕获它。

    RequestInterceptor.java

    public class RequestInterceptor implements Interceptor {
    
        ConnectivityManager connectivityManager;
        Application mApplication;
    
        @Inject
        public RequestInterceptor(Application mApplication) {
            this.mApplication = mApplication;
            connectivityManager = (ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE);
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            if (isConnected()) {
                throw new OfflineException();
            }
    
            Request.Builder r = chain.request().newBuilder();
            return chain.proceed(r.build());
        }
    
        protected boolean isConnected() {
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            return networkInfo != null && networkInfo.isConnectedOrConnecting();
        }
    
        public class OfflineException extends IOException {
    
            @Override
            public String getMessage() {
                return mApplication.getResources().getString(R.string.app_no_connectivity);
            }
    
        }
    
    }
    

    NetModule.java

    import android.app.Application;
    import android.content.SharedPreferences;
    import android.preference.PreferenceManager;
    
    import com.google.gson.FieldNamingPolicy;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    import java.util.concurrent.TimeUnit;
    
    import javax.inject.Singleton;
    
    import commons.LinksAndKeys;
    import dagger.Module;
    import dagger.Provides;
    import okhttp3.Cache;
    import okhttp3.OkHttpClient;
    import retrofitDagger.retrofitUtils.RequestInterceptor;
    import retrofit2.Retrofit;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    
    @Module
    public class NetModule {
    
        String mBaseUrl;
        Application mApplication;
    
        // Constructor needs one parameter to instantiate.
        public NetModule(String baseUrl, Application application) {
            this.mBaseUrl = baseUrl;
            this.mApplication = application;
        }
    
        // Dagger will only look for methods annotated with @Provides
        @Provides
        @Singleton
        // Application reference must come from AppModule.class
        SharedPreferences providesSharedPreferences(Application application) {
            return PreferenceManager.getDefaultSharedPreferences(application);
        }
    
        @Provides
        @Singleton
        Application providesApplication() {
            return mApplication;
        }
    
        @Provides
        @Singleton
        Cache provideOkHttpCache(Application application) {
            int cacheSize = 10 * 1024 * 1024; // 10 MiB
            Cache cache = new Cache(application.getCacheDir(), cacheSize);
            return cache;
        }
    
        @Provides
        @Singleton
        Gson provideGson() {
            GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
            return gsonBuilder.create();
        }
    
        @Provides
        @Singleton
        OkHttpClient provideOkHttpClient(Cache cache) {
            OkHttpClient.Builder client = new OkHttpClient.Builder();
            client.cache(cache);
            client.addInterceptor(new  RequestInterceptor(mApplication));
            client.readTimeout(LinksAndKeys.READ_TIMEOUT, TimeUnit.SECONDS);
            client.connectTimeout(LinksAndKeys.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
            return client.build();
        }
    
        @Provides
        @Singleton
        Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
            Retrofit retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .baseUrl(mBaseUrl)
                    .client(okHttpClient)
                    .build();
            return retrofit;
        }
    }
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        @Inject
        Retrofit retrofit;
        TextView textView;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ((App) getApplication()).getNetComponent().inject(this);
    
            //Create textview and findViewByID
            textView = (TextView) findViewById(R.id.textview_post);
            //Create a retrofit call object
            Call<List<Post>> posts = retrofit.create(Restapi.class).getPosts();
    
            //Enque the call
            posts.enqueue(new Callback<List<Post>>() {
                @Override
                public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
                   //Set the response to the textview
                    textView.setText(response.body().get(0).getBody());
    
                }
    
                @Override
                public void onFailure(Call<List<Post>> call, Throwable t) {
                    //Set the error to the textview
                    textView.setText(t.toString());
                }
            });
        }
    }
    

2 个答案:

答案 0 :(得分:2)

据我所知,没有互联网连接,RetrofitError包含一个ConnectionException作为原因。

public class RetrofitErrorHandler implements ErrorHandler {

    @Override
    public Throwable handleError(RetrofitError cause) {
        if (cause.isNetworkError()) {
            if (cause.getCause() instanceof SocketTimeoutException) {
                  /* your code here*/ 
                return new MyConnectionTimeoutException();
            } else {
                /* your code here*/
                return new MyNoConnectionException();
            }
        } else {
            //Do whatever you want to do if there is not a network error.  
        }
    }
}

或者您可以创建一个自定义Retrofit客户端,在执行请求之前检查连接并抛出异常。

public class ConnectivityCheck implements Client {

    Logger log = LoggerFactory.getLogger(ConnectivityCheck.class);

    public ConnectivityCheck (Client wrappedClient, NetworkConnectivityManager ncm) {
        this.wrappedClient = wrappedClient;
        this.ncm = ncm;
    }

    Client wrappedClient;
    private NetworkConnectivityManager ncm;

    @Override
    public Response execute(Request request) throws IOException {
        if (!ncm.isConnected()) {
            log.debug("No connectivity %s ", request);
            throw new NoConnectivityException("No connectivity");
        }
        return wrappedClient.execute(request);
    }
}

然后在配置RestAdapter时使用它

RestAdapter.Builder().setEndpoint(serverHost)
                     .setClient(new ConnectivityCheck(new OkHttpClient(), ...))

答案 1 :(得分:0)

据我所知,我不认为Retrofit支持“通话时间的连接检查”,我认为这不是你想要的。

尝试在通话前检查连接,例如

private void sendData() {
    if( isConnected ) {
          switch(call) {
               case "userSignIn":
                      Call !
                      break;
               ...
    }
}

也许你也可以查看solution