android okhttp+retrofit+hilt+rxjava简单使用
app的build.gradle如下
plugins {
id 'com.android.application'
id 'com.google.dagger.hilt.android'//使用hilt
}
android {
compileSdk 33
defaultConfig {
applicationId "com.nyw.okhttpretrofitrxjava"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
//okhttp引入
implementation("com.squareup.okhttp3:okhttp:4.10.0")
// okhttp3拦截器
implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
//添加rxjava
implementation 'io.reactivex.rxjava2:rxjava:2.2.10'
//添加rxandroid 线程切换
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
//添加rxjava adapter 数据适配
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// retrofit转实体
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// retrofit 转字符
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
//添加hilt依赖项注入库 https://developer.android.com/training/dependency-injection/hilt-android?hl=zh-cn#groovy
implementation "com.google.dagger:hilt-android:2.28-alpha"
annotationProcessor 'com.google.dagger:hilt-android-compiler:2.28-alpha'
}
ApiService如下
package com.nyw.okhttpretrofitrxjava;
import com.nyw.okhttpretrofitrxjava.network.ResponseData;
import com.nyw.okhttpretrofitrxjava.network.bean.UpdateAppInfo;
import com.nyw.okhttpretrofitrxjava.network.bean.UserInfo;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.MultipartBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Query;
public interface ApiService {
// @GET就是get请求,可以改成post或put
// @GET("api/index/version")
// Call<String> test(@Query("title") String data);
// @POST("api/index/version")
// //post请求
// Call<String> testPost(@Query("title") String data);
//
// //表单方式,使用了@Field,必须使用@FormUrlEncoded,必须是post请求,参数不会在url中拼接传递
// @POST("api/index/version")
// @FormUrlEncoded
// Call<String> test_field(@Field("title") String data);
//
// //表单方式,使用了@FieldMap,可以传递多个参数,必须是post请求,参数不会在url中拼接传递
// @POST("api/index/version")
// @FormUrlEncoded
// Call<String> test_Map(@FieldMap Map<String,String> data);
//
// //body方式提交,使用了@Body,@Body后面是实体数据类型,必须是post请求,参数不会在url中拼接传递
// //UpdateAppInfo就是ResponseData类中data范型里的数据类型,是服务器返回的JSON数据类型,要一致才可以解析JSON成功
// @POST("api/index/version")
// Call<ResponseData<UpdateAppInfo>> test_json(@Body UserInfo data);
//
// //文件上传,使用@Multipart,只能是post请求,使用@Part
// @Multipart
// @POST
// Call<ResponseData<String>> updataFile(@Part MultipartBody.Part part);
//使用rxjava测试接口的
@POST("api/index/version")
Observable<ResponseData<UpdateAppInfo>> testApi(@Body UserInfo data);
}
MyApplication代码如下
package com.nyw.okhttpretrofitrxjava;
import android.app.Application;
import dagger.hilt.android.HiltAndroidApp;
@HiltAndroidApp
public class MyApplication extends Application {
}
activity代码如下
package com.nyw.okhttpretrofitrxjava;
import androidx.annotation.MainThread;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import com.nyw.okhttpretrofitrxjava.network.ResponseData;
import com.nyw.okhttpretrofitrxjava.network.bean.UpdateAppInfo;
import com.nyw.okhttpretrofitrxjava.network.bean.UserInfo;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
//@AndroidEntryPoint声明是可以驻入的,生成对应代码进行初始化操作
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
@Inject
ApiService apiService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiService.testApi(new UserInfo("名字","性别","地址"))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ResponseData<UpdateAppInfo>>() {
@Override
public void accept(ResponseData<UpdateAppInfo> updateAppInfoResponseData) throws Exception {
//正常处理
Log.i("sflkjskfsfjsfs",updateAppInfoResponseData.getData().getContent());
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
//异常处理
}
});
}
}
NetWordModule如下
package com.nyw.okhttpretrofitrxjava.network;
import android.util.Log;
import androidx.annotation.NonNull;
import com.nyw.okhttpretrofitrxjava.ApiService;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.components.ApplicationComponent;
import io.reactivex.plugins.RxJavaPlugins;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
//@InstallIn 注释装载到ApplicationComponent.class
//注解声明为@Module
@InstallIn(ApplicationComponent.class)
@Module
public class NetWordModule {
// @Singleton是设置为单例,防止重复创建
@Singleton
@Provides
OkHttpClient okHttpClient(){
// Retrofit使用的拦截器
HttpLoggingInterceptor httpLoggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(@NonNull String s) {
Log.i("asjfksjsfdfskfjs",s);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);
return new OkHttpClient().newBuilder().addInterceptor(httpLoggingInterceptor).build();
}
//这里只需要声明OkHttpClient对象,下面.client会自动调用okHttpClient
@Singleton
@Provides
Retrofit provideRetrofit(OkHttpClient okHttpClient ){
//使用retrofit
return new Retrofit.Builder()
.baseUrl("http://mt.mmm.com/")
// .addConverterFactory(ScalarsConverterFactory.create())//提交字符串数据
.addConverterFactory(GsonConverterFactory.create())//提交JSON数据
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加适配器
.client(okHttpClient)
.build();
}
//创建接口,取得apiService对象
@Singleton
@Provides
ApiService provideApiService(Retrofit retrofit){
return retrofit.create(ApiService.class);
}
}
ResponseData如下
package com.nyw.okhttpretrofitrxjava.network;
public class ResponseData<T> {
private String err_code;
private String msg;
private T data;//data是可变的,可以设置为范型
public String getErr_code() {
return err_code;
}
public void setErr_code(String err_code) {
this.err_code = err_code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
UserInfo如下
package com.nyw.okhttpretrofitrxjava.network.bean;
public class UserInfo {
String name;
String sex;
String adress;
public UserInfo(String name, String sex, String adress) {
this.name = name;
this.sex = sex;
this.adress = adress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
}
UpdateAppInfo如下
package com.nyw.okhttpretrofitrxjava.network.bean;
public class UpdateAppInfo {
private String id;
private String type;
private String enforece;
private String version;
private String name;
private String url;
private String content;
private String create_time;
private String version_name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEnforece() {
return enforece;
}
public void setEnforece(String enforece) {
this.enforece = enforece;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreate_time() {
return create_time;
}
public void setCreate_time(String create_time) {
this.create_time = create_time;
}
public String getVersion_name() {
return version_name;
}
public void setVersion_name(String version_name) {
this.version_name = version_name;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.nyw.okhttpretrofitrxjava">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".MyApplication"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.OkhttpRetrofitRxjava"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths_public"
tools:replace="android:resource" />
</provider>
</application>
</manifest>
file_paths_public如下
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!--内置SD卡 Environment.getExternalStorageDirectory() .表示共享所有的目录,也可以指定共享的目录-->
<external-path
name="external-path"
path="." />
<!--内置SD卡 Context.getExternalCacheDir() .表示共享所有的目录,也可以指定共享的目录-->
<external-cache-path
name="external-cache-path"
path="." />
<!--内置SD卡 Context.getExternalFilesDir(null) .表示共享所有的目录,也可以指定共享的目录-->
<external-files-path
name="external-files-path"
path="." />
<!--data目录下 Context.getFilesDir() .表示共享所有的目录,也可以指定共享的目录-->
<files-path
name="files_path"
path="." />
<!--data缓存目录 Context.getCacheDir() .表示共享所有的目录,也可以指定共享的目录-->
<cache-path
name="cache-path"
path="." />
<!--这个标签Android官方文档中是没有提及,Android设备的根目录,该目录下包含着手机内部存储器,外置SD卡等所有文件的目录-->
<root-path
name="name"
path="." />
<external-path
name="external"
path="." />
<external-files-path
name="Download"
path="." />
<external-files-path
name="umeng_cache"
path="umeng_cache/" />
<files-path
name="int_root"
path="/" />
<!--2、对应应用默认缓存根目录:Context.getCacheDir()-->
<cache-path
name="app_cache"
path="/" />
<!--3、对应外部内存卡根目录:Environment.getExternalStorageDirectory()-->
<external-path
name="ext_root"
path="Documents/" />
<!--4、对应外部内存卡根目录下的APP公共目录:Context.getExternalFileDir(String)-->
<external-files-path
name="ext_pub"
path="/" />
<!--5、对应外部内存卡根目录下的APP缓存目录:Context.getExternalCacheDir()-->
<external-cache-path
name="ext_cache"
path="/" />
</paths>
network_security_config如下
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>