android okhttp+RxJava+retrofit网络请求框架用法解析 使用举例

前言

    这个网络请求框架使用的是MVP模式,用习惯之后你会发现这个框架写网络请求很方便,因为它封装的很好,而且这个框架也是目前android开发比较主流的网络请求框架,所以写一篇文章记录一下使用这个框架的大致流程。

正文

1.添加项目依赖库:

    //components
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.blankj:utilcode:1.23.7'
    //rx
    implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    //network
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    implementation 'com.squareup.okhttp3:okhttp:3.11.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
    implementation('com.github.ihsanbal:LoggingInterceptor:3.0.0') {
        exclude group: 'org.json', module: 'json'
    }
    //di
    implementation 'com.google.dagger:dagger:2.17'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.17'
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    implementation 'com.android.support:multidex:1.0.3'
    implementation 'me.yokeyword:fragmentation:1.3.3'
    implementation 'com.orhanobut:logger:2.1.1'

工程目录下build目录修改如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        maven { url "https://dl.bintray.com/thelasterstar/maven/" }
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        mavenCentral()
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2.初始化okhttp设置:

@Module
public class HttpModule {

    @Singleton
    @Provides
    Retrofit.Builder provideRetrofitBuilder() {
        return new Retrofit.Builder();
    }


    @Singleton
    @Provides
    OkHttpClient.Builder provideOkHttpBuilder() {
        return new OkHttpClient.Builder();
    }

    @Singleton
    @Provides
    @MainUrl
    Retrofit provideZhihuRetrofit(Retrofit.Builder builder, OkHttpClient client) {
        return createRetrofit(builder, client, Constant.BASE_HOST);
    }

    @Singleton
    @Provides
    OkHttpClient provideClient(OkHttpClient.Builder builder) {
        if (BuildConfig.DEBUG) {

            LoggingInterceptor httpLoggingInterceptor = new LoggingInterceptor.Builder()
                    .loggable(BuildConfig.DEBUG)
                    .setLevel(Level.BASIC)
                    .log(Platform.INFO)
                    .request("Request")
                    .response("Response")
                    .build();
//            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
//            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
            builder.addInterceptor(httpLoggingInterceptor);
        }
        File cacheFile = new File(Constant.PATH_CACHE);
        Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
        Interceptor cacheInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!SystemUtil.isNetworkConnected()) {
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }
                Response response = chain.proceed(request);
                if (SystemUtil.isNetworkConnected()) {
                    int maxAge = 0;
                    // 有网络时, 不缓存, 最大保存时长为0
                    response.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .removeHeader("Pragma")
                            .build();
                } else {
                    // 无网络时,设置超时为4周
                    int maxStale = 60 * 60 * 24 * 28;
                    response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .removeHeader("Pragma")
                            .build();
                }
                return response;
            }
        };
//        Interceptor apikey = new Interceptor() {
//            @Override
//            public Response intercept(Chain chain) throws IOException {
//                Request request = chain.request();
//                request = request.newBuilder()
//                        .addHeader("apikey",Constants.KEY_API)
//                        .build();
//                return chain.proceed(request);
//            }
//        }
//        设置统一的请求头部参数
//        builder.addInterceptor(apikey);
        //设置缓存
        builder.addNetworkInterceptor(cacheInterceptor);
        builder.addInterceptor(cacheInterceptor);
        builder.cache(cache);
        //设置超时
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(20, TimeUnit.SECONDS);
        builder.writeTimeout(20, TimeUnit.SECONDS);
        //错误重连
        builder.retryOnConnectionFailure(true);
        return builder.build();
    }

    @Singleton
    @Provides
    MainApi provideMainService(@MainUrl Retrofit retrofit) {
        return retrofit.create(MainApi.class);
    }

    private Retrofit createRetrofit(Retrofit.Builder builder, OkHttpClient client, String url) {
        return builder
                .baseUrl(url)
                .client(client)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
}

细节解析:

1.该类中使用到的一些标签不要遗漏,尤其是类名上的@Module标签;

2.Constant.BASE_HOST--使用你的接口DoMain,比如你的接口请求完整地址是https://www.baidu.com/v2/draft/add,那么这个参数应该填入https://www.baidu.com/;

3.按照上面的写法,请求和返回的相关数据都会打印到日志里,需要自定义打印日志信息的话自行修改provideClient方法中的httpLoggingInterceptor;

4.provideMainService中的MainApi.class是你的接口声明类,下一步会提到。

2.创建接口声明类MainApi

public interface MainApi {
    @POST("courses/index/")
    Flowable<EditFrameInfo> getUserInfo();

    @Multipart
    @POST("v2/draft/add")
    Flowable<PictureBean> saveCoursewareInfo(@PartMap Map<String, RequestBody> map);

    @GET("attach/materials")
    Flowable<ResourcesBean> getResources(@Query("type") String type);
}

这里我选择的代码把常用的几种请求方式都涵盖了,第一种是不需要参数的post请求,第二种是需要参数的post请求,第三种是带参数的get请求,根据你的请求类型自行选用即可。这里如果你是post的带参数请求,可以统一把参数格式都写成@PartMap Map<String, RequestBody> map这样。

细节解析:

1.@POST("v2/draft/add")--括号里的是你想要调用的地址domain后面的部分。

3.实现MainApi中的接口

1.定义HttpHelper接口:

public interface HttpHelper {
    Flowable<PictureBean> saveCoursewareInfo(@PartMap Map<String, RequestBody> map);
}

这里直接把MainApi里定义的接口除了标签部分复制进来就可以了。

2.实现HttpHelper接口:

public class RetrofitHelper implements HttpHelper {
    private MainApi mMainApiService;

    @Inject
    public RetrofitHelper(MainApi mMainApiService) {
        this.mMainApiService = mMainApiService;
    }

    @Override
    public Flowable<PictureBean> saveCoursewareInfo(Map<String, RequestBody> map) {
        return mMainApiService.saveCoursewareInfo(map);
    }
}

注意这里的@Inject别忘记加。

3.创建DataManager类:

该类用于管理所有的数据请求,就是封装了一层方法调用。

public class DataManager implements HttpHelper {
    HttpHelper mHttpHelper;

    public DataManager(HttpHelper httpHelper) {
        mHttpHelper = httpHelper;
    }

    @Override
    public Flowable<PictureBean> saveCoursewareInfo(Map<String, RequestBody> map) {
        return mHttpHelper.saveCoursewareInfo(map);
    }
}

4.定义Contract接口:

public interface MainContract {
    interface View extends BaseView {
        void responseCoursewareId(int id);
    }

    interface Presenter extends BasePresenter<View> {
        void saveCoursewareLib(Map<String, RequestBody> map);
    }
}

Presenter接口定义请求方法,View接口定义回调方法。简单来说就是你想调用MainApi里定义的接口就用Presenter里的方法去请求,请求之后的会回调View里对应的方法。

5.定义Presenter:

public class MainPresenter extends RxPresenter<MainContract.View> implements MainContract.Presenter {

    private static final String TAG = MainPresenter.class.getSimpleName();

    DataManager dataManager;

    @Inject
    public MainPresenter(DataManager dataManager) {
        this.dataManager = dataManager;
    }

    @Override
    public void saveCoursewareLib(Map<String, RequestBody> map) {
        addSubscribe(dataManager.saveCoursewareInfo(map)
                .compose(RxUtil.rxSchedulerHelper())
                .subscribeWith(new CommonSubscriber<PictureBean>(mView) {
                    @Override
                    public void onNext(PictureBean pictureBean) {
                        if (pictureBean.getData() != null) {
                            if (pictureBean.getData().getCode() == Constant.NET_REQUEST_OK && mView != null) {
                                mView.responseCoursewareId(pictureBean.getData().getCourseId());
                                ToastUtils.showShort(pictureBean.getMsg());
                            } else {
                                LogUtil.e(TAG + " request fail or mView is null");
                            }
                        } else {
                            ToastUtils.showShort(pictureBean.getMsg());
                        }
                    }
                }));
    }
}

Presenter实现Contract里的接口,记住不要遗漏构造函数上方的@Injeft标签。

除了onNext方法以外,还有

                               @Override
                               public void onError(Throwable e) {
                                   super.onError(e);
                               }

                               @Override
                               protected void onStart() {
                                   super.onStart();
                               }

                               @Override
                               public void onComplete() {
                                   super.onComplete();
                               }

根据自己需求自行添加。

细节解析:

1.onNext返回的参数PictureBean是用来解析这个接口返回的数据写的实体类,框架会自动将接口返回的数据按照这个实体类去解析,该实体类根据自己的接口返回数据去写,如果你的AS安装了GsonFormat插件,使用插件直接生成一个实体类就行了。

附上代码中用到的实体类代码作为参考:

public class PictureBean {

    /**
     * errorCode : 0
     * msg : success
     * data : {"id":1,"url":"asadsa"}
     */

    private int errorCode;
    private String msg;
    private DataBean data;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public static class DataBean {
        /**
         * id : 1
         * url : asadsa
         */

        private int imgId;
        private String url;
        private int code;
        private int chunk;
        private int courseId;
        private int actualNum;
        private int lastChunk;

        public int getImgId() {
            return imgId;
        }

        public void setImgId(int imgId) {
            this.imgId = imgId;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public int getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public int getChunk() {
            return chunk;
        }

        public void setChunk(int chunk) {
            this.chunk = chunk;
        }

        public int getCourseId() {
            return courseId;
        }

        public void setCourseId(int courseId) {
            this.courseId = courseId;
        }

        public int getActualNum() {
            return actualNum;
        }

        public void setActualNum(int actualNum) {
            this.actualNum = actualNum;
        }

        public int getLastChunk() {
            return lastChunk;
        }

        public void setLastChunk(int lastChunk) {
            this.lastChunk = lastChunk;
        }

        @Override
        public String toString() {
            return "DataBean{" +

                    "imgId=" + imgId +
                    ", url='" + url + '\'' +
                    ", code=" + code +
                    ", chunk=" + chunk +
                    ", courseId=" + courseId +
                    ", actualNum=" + actualNum +
                    ", lastChunk=" + lastChunk +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "PictureBean{" +
                "errorCode=" + errorCode +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

6.在代码中使用

这里需要提到几个基类,Activity基类和Fragment基类:

1.SimpleActivity


/**
 * Created by codeest on 16/8/11.
 * 无MVP的activity基类
 */

public abstract class SimpleActivity extends SupportActivity {

    protected Activity mContext;
    private Unbinder mUnBinder;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayout());
        mUnBinder = ButterKnife.bind(this);
        mContext = this;
        if(Utils.checkLogin(mContext)){
            onViewCreated();
            App.getInstance().addActivity(this);
            initEventAndData();
        }
    }

    protected void setToolBar(Toolbar toolbar, String title) {
        toolbar.setTitle(title);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackPressedSupport();
            }
        });
    }

    protected void onViewCreated() {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        App.getInstance().removeActivity(this);
        mUnBinder.unbind();
        System.gc();
    }

    protected abstract int getLayout();

    protected abstract void initEventAndData();
}

项目中所有Activity的基类,如果不涉及到网络请求,就继承这个,如果涉及到网络请求则继承下面提到的这个。

2.BaseActivity

/**
 * Created by codeest on 2016/8/2.
 * MVP activity基类
 */
public abstract class BaseActivity<T extends BasePresenter> extends SimpleActivity implements BaseView {

    @Inject
    protected T mPresenter;

    protected LoadingUtil mLoading;

    protected ActivityComponent getActivityComponent() {
        return DaggerActivityComponent.builder()
                .appComponent(App.getAppComponent())
                .activityModule(getActivityModule())
                .build();
    }

    protected ActivityModule getActivityModule() {
        return new ActivityModule(this);
    }

    @Override
    protected void onViewCreated() {
        super.onViewCreated();
        initInject();

        mLoading = LoadingUtil.getInstance(new ProgressDialogHandler(this, new ProgressCancelListener() {
            @Override
            public void onCancelProgress() {
                //等待框显示时 取消监听
            }

            @Override
            public void onCancelDispose() {
                //等待框显示时 返回键监听
            }
        }, false));
        if (mPresenter != null)
            mPresenter.attachView(this);
    }

    @Override
    protected void onDestroy() {
        if (mPresenter != null)
            mPresenter.detachView();
        super.onDestroy();
    }

    @Override
    public void showErrorMsg(String msg) {
        SnackbarUtil.show(((ViewGroup) findViewById(android.R.id.content)).getChildAt(0), msg);
    }

//    @Override
//    public void useNightMode(boolean isNight) {
//        if (isNight) {
//            AppCompatDelegate.setDefaultNightMode(
//                    AppCompatDelegate.MODE_NIGHT_YES);
//        } else {
//            AppCompatDelegate.setDefaultNightMode(
//                    AppCompatDelegate.MODE_NIGHT_NO);
//        }
//        recreate();
//    }

    @Override
    public void stateError() {

    }

    @Override
    public void stateEmpty() {

    }

    @Override
    public void stateLoading() {

    }

    @Override
    public void stateMain() {

    }

    protected abstract void initInject();
}

3.SimpleFragment


/**
 * Created by codeest on 16/8/11.
 * 无MVP的Fragment基类
 */

public abstract class SimpleFragment extends SupportFragment {

    protected View mView;
    protected Activity mActivity;
    protected Context mContext;
    private Unbinder mUnBinder;
    protected boolean isInited = false;

    @Override
    public void onAttach(Context context) {
        mActivity = (Activity) context;
        mContext = context;
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mView = inflater.inflate(getLayoutId(), null);
        return mView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mUnBinder = ButterKnife.bind(this, view);
    }

    @Override
    public void onLazyInitView(@Nullable Bundle savedInstanceState) {
        super.onLazyInitView(savedInstanceState);
        isInited = true;
        initEventAndData();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mUnBinder.unbind();
    }

    protected abstract int getLayoutId();
    protected abstract void initEventAndData();
}

跟Activity一样。

4.BaseFragment

/**
 * Created by codeest on 2016/8/2.
 * MVP Fragment基类
 */
public abstract class BaseFragment<T extends BasePresenter> extends SimpleFragment implements BaseView {

    @Inject
    protected T mPresenter;

    protected FragmentComponent getFragmentComponent(){
        return DaggerFragmentComponent.builder()
                .appComponent(App.getAppComponent())
                .fragmentModule(getFragmentModule())
                .build();
    }

    protected FragmentModule getFragmentModule(){
        return new FragmentModule(this);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        initInject();
        mPresenter.attachView(this);
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onDestroyView() {
        if (mPresenter != null) mPresenter.detachView();
        super.onDestroyView();
    }

    @Override
    public void showErrorMsg(String msg) {
        SnackbarUtil.show(((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0), msg);
    }

//    @Override
//    public void useNightMode(boolean isNight) {
//
//    }

    @Override
    public void stateError() {

    }

    @Override
    public void stateEmpty() {

    }

    @Override
    public void stateLoading() {

    }

    @Override
    public void stateMain() {

    }

    protected abstract void initInject();
}

5.在Activity中进行网络请求:

public class MainActivity extends BaseActivity<MainPresenter> implements MainContract.View{

    @Override
    protected void initInject() {
        getActivityComponent().inject(this);
    }

    @Override
    protected int getLayout() {
        return R.layout.activity_main;
    }

    @Override
    protected void initEventAndData() {
        int mills = Utils.getCurrentTimeMills();
        Map<String, RequestBody> map = new HashMap<>();
        if (course_id != 0) {
            map.put("course_id", MultipartBody.create(MultipartBody.FORM, String.valueOf(course_id)));
        }
        map.put("user_id", MultipartBody.create(MultipartBody.FORM, String.valueOf(SharedPreferencesUtil.getIntDate(Constant.SPKEY_USERID))));
        map.put("title", MultipartBody.create(MultipartBody.FORM, ""));
        map.put("content", MultipartBody.create(MultipartBody.FORM, new Gson().toJson(mCoursewareInfo)));
        map.put("timestamp", MultipartBody.create(MultipartBody.FORM, mills + ""));
        map.put("token", MultipartBody.create(MultipartBody.FORM, MD5Utils.md5(String.valueOf(SharedPreferencesUtil.getIntDate(Constant.SPKEY_USERID)) + mills + Constant.KEY)));
        mPresenter.saveCoursewareLib(map);
    }
    
    @Override
    public void responseCoursewareId(int id) {
        //saveCoursewareLib的请求回调
    }

}

这里用请求saveCoursewareLib方法举例,就是我们上面有过声明的一个请求方法。这里有个带有标签@Inject的方法,里面有一句getActivityComponent().inject(this); 这个方法的调用就需要我们配置Activity组件了,另外会附上Fragment组件的配置代码。

6.Activity组件配置:

@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {

    Activity getActivity();

    void inject(MainActivity mainActivity);
}

//移到项目中请另外创建一个类,文章中偷懒写在一起了,并不是上面的内部类
@Module
public class ActivityModule {
    private Activity mActivity;

    public ActivityModule(Activity activity) {
        this.mActivity = activity;
    }

    @Provides
    @ActivityScope
    public Activity provideActivity() {
        return mActivity;
    }
}

7.Fragment组件配置:

@FragmentScope
@Component(dependencies = AppComponent.class, modules = FragmentModule.class)
public interface FragmentComponent {

    Activity getActivity();

    void inject(CoursewareDraftFragment coursewareDraftFragment);
}

//跟Activity组件一样,偷懒写在一起了
@Module
public class FragmentModule {

    private Fragment fragment;

    public FragmentModule(Fragment fragment) {
        this.fragment = fragment;
    }

    @Provides
    @FragmentScope
    public Activity provideActivity() {
        return fragment.getActivity();
    }
}

//使用:
    @Override
    protected void initInject() {
        getFragmentComponent().inject(this);
    }

8.附上全局接口回调定义类,兴许你能用得着 

public abstract class CommonSubscriber<T> extends ResourceSubscriber<T> {
    private BaseView mView;
    private String mErrorMsg;
    private boolean isShowErrorState = true;

    protected CommonSubscriber(BaseView view) {
        this.mView = view;
    }

    protected CommonSubscriber(BaseView view, String errorMsg) {
        this.mView = view;
        this.mErrorMsg = errorMsg;
    }

    protected CommonSubscriber(BaseView view, boolean isShowErrorState) {
        this.mView = view;
        this.isShowErrorState = isShowErrorState;
    }

    protected CommonSubscriber(BaseView view, String errorMsg, boolean isShowErrorState) {
        this.mView = view;
        this.mErrorMsg = errorMsg;
        this.isShowErrorState = isShowErrorState;
    }

    @Override
    public void onComplete() {

    }

    @Override
    public void onError(Throwable e) {
        if (mView == null) {
            return;
        }
        if (mErrorMsg != null && !TextUtils.isEmpty(mErrorMsg)) {
            mView.showErrorMsg(mErrorMsg);
        } else if (e instanceof ApiException) {
            mView.showErrorMsg(e.getMessage());
        } else if (e instanceof HttpException) {
            if (NetworkUtils.isConnected())
                mView.showErrorMsg("数据请求异常ヽ(≧Д≦)ノ");
            else
                mView.showErrorMsg("网络异常,请检查网络是否连接ヽ(≧Д≦)ノ");
        } else if (e instanceof SocketTimeoutException) {
            mView.showErrorMsg("网络不佳,请重新加载!ヽ(≧Д≦)ノ");
        } else if (e instanceof JsonParseException) {
            mView.showErrorMsg("数据解析错误ヽ(≧Д≦)ノ");
        } else {
            mView.showErrorMsg("未知错误ヽ(≧Д≦)ノ");
            LogUtil.d(e.toString());
        }
        if (isShowErrorState) {
            mView.stateError();
        }
        e.printStackTrace();
    }
}

结语

    一个流程走下来,涉及到的东西挺多的,所以刚接触的话可能会有点摸不着北,其实每个接口的定义和使用都是这么一套东西,可以试着自己走一两个接口的全流程,走几遍之后流程熟悉了就好了。熟悉之后你会发现这个框架用起来还是很方便的。

    如果这篇文章对你有帮助,点一下免费的赞和关注吧,这些是我更博的动力~

    如果遇到问题,欢迎下方留言。

    最后推荐给一些想进大厂或者还没有拿到心仪offer的攻城狮们一本书,由大厂java面试官胡书敏编写,满满的干货,助你进到想去的公司。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: OkHttpRxJavaRetrofit是个非常常用的组合,用来进行网络请求和处理。 首先,OkHttp是一个开源的HTTP客户端,提供了简洁的接口,用于与服务器进行通信,并且支持HTTP/2协议,拥有连接池、请求重试和缓存等功能。 然后,RxJava是一个基于观察者模式的异步编程库,可以用于处理异步操作,如网络请求、文件IO等。它的核心是Observable(被观察者)和Subscriber(订阅者),通过各种操作符可以对数据进行变换和处理。 最后,Retrofit是一个RESTful风格的HTTP请求库,它基于OkHttp使用Retrofit的注解和接口定义的方式,可以方便地进行网络请求。它支持动态代理,可以将网络请求接口转化为对应的HTTP请求,支持同步和异步请求,并且可以将响应数据转化为Java对象。 综上所述,我们可以使用OkHttp作为底层网络库,然后结合RxJavaRetrofit进行网络请求和数据处理。使用Retrofit的注解和接口定义方式,可以简化网络请求的代码,并且通过RxJava的操作符可以对请求结果进行变换和处理,使得代码更加清晰和可读性。 在使用过程中,可以先创建一个Retrofit实例,并指定OkHttpClient作为网络客户端,然后定义一个接口,在该接口中使用Retrofit的注解,定义网络请求的方法。最后,通过创建该接口的实例,即可进行网络请求,并结合RxJava进行操作。 总之,使用OkHttpRxJavaRetrofit组合进行网络请求可以提高效率和可读性,并且可以处理各种复杂的网络场景,是一种非常实用的方式。 ### 回答2: OKHTTPRXJavaRetrofitAndroid开发中常用的三个库,可以一起使用来进行网络请求和数据处理。 OKHTTP是一个用于处理网络请求的库,可以发送HTTP请求并获取服务器返回的数据。它提供了简洁的API和高效的网络堆栈,可以很好地处理网络请求。我们可以使用OKHTTP来发送SOAP请求到WebService,并获得响应。 RXJava是一个流编程库,它提供了一种被观察者和观察者模式,可以简化异步操作和事件处理。我们可以使用RXJava来处理OKHTTP返回的响应数据,在主线程或后台线程中进行处理,实现数据的异步处理和流式编程。 Retrofit是一个基于OKHTTP的RESTful风格的网络请求库,它提供了一种简洁的方式来定义和发送HTTP请求,并将响应转换为可用的Java对象。我们可以使用Retrofit来定义WebService接口,然后使用注解来指定请求方法、路径和参数,Retrofit会自动帮我们处理请求和响应。 通过OKHTTP的原生支持、RXJava的异步处理和Retrofit网络请求,我们可以很方便地使用OKHTTPRXJavaRetrofit一起发送WebService请求。首先,我们可以使用Retrofit定义WebService接口,再使用RXJava来处理OKHTTP返回的响应数据,实现简洁高效的网络请求和数据处理。 综上所述,OKHTTPRXJavaRetrofitAndroid开发中常用的网络请求库,它们能够很好地协作,实现对WebService的请求和响应的处理。通过使用它们,我们可以简化网络请求的编写,并实现高效的数据处理。 ### 回答3: OkHttpRxJavaRetrofit是三个在Android开发中常用的网络请求库,它们在一起能够提供更加便捷和高效的网络请求处理。 首先,OkHttp是一个开源的HTTP客户端,它能够处理网络请求、连接管理、请求重试等一系列的网络相关事务。它的特点是简单易用、性能优越、可定制性强。我们可以通过使用OkHttp来发送和接收基于HTTP的请求响应,并进行网络请求的管理和处理。 其次,RxJava是一个响应式编程框架,它基于观察者模式和函数式编程的思想,提供了一系列强大的操作符和线程切换的能力。我们可以使用RxJava来处理异步任务,加快网络请求的响应时间,并且提供方便的线程切换和错误处理机制。 最后,Retrofit是一个RESTful风格的网络请求框架,它结合了OkHttpRxJava的强大功能。它提供了一种简单的方式来定义和处理RESTful API的请求和响应。我们可以使用Retrofit来创建和处理webservice的请求,根据API的接口定义来发送请求,并将返回的结果映射到Java对象中。 综上所述,使用OkHttpRxJavaRetrofit能够方便地进行webservice的网络请求,并在处理过程中提供更好的性能和便利性。这三个库的结合能够大大简化网络请求的开发工作,提高开发效率,并提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JesseAndroid

每一份支持都是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值