Android Retrofit+LiveData+ViewModel架构

1、build.gradle添加依赖

    //jetpack组件库
    api 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'

    api "com.google.code.gson:gson:2.8.5"

    //retrofit网络请求 、 okhttp网络请求和Rxjava3
    api "com.squareup.okhttp3:logging-interceptor:4.7.2"
    api "com.squareup.retrofit2:converter-gson:2.9.0"
    api "com.squareup.retrofit2:retrofit:2.9.0"
    api "com.squareup.retrofit2:adapter-rxjava3:2.9.0"

    //glide图片加载
    api 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

    //RxAndroid RxLifecycle是为了防止RxJava中subscription导致内存泄漏而诞生的,核心思想是通过监听Activity、Fragment的生命周期,来自动断开subscription以防止内存泄漏
    api 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
    api 'com.trello.rxlifecycle4:rxlifecycle-components:4.0.2'
    api 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'

    api 'com.alibaba:arouter-api:1.5.1'

2、新建BaseActivity、BaseFragment   以防止内存泄漏  继承RxAppCompatActivity和RxFragment

public class BaseActivity extends RxAppCompatActivity {
}


public class BaseFragment extends RxFragment {
}

3、Application增加registerActivityLifecycleCallbacks  可以监听到 Activity 的状态,从而可以判断 APP 是否在前台或者后台等

public class EnterApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        AppGlobalVar.appContext = base;
        AppGlobalVar.currentLanguage = LanguageHandler.getInstance().getLanguage();
        super.attachBaseContext(LanguageHandler.getInstance().setLocal(base));
    }

    @Override
    public void onCreate() {
        super.onCreate();

        CrashHandler.getInstance().init(this);

        //路由初始化
        if (AppGlobalVar.isDebug) {
            ARouter.openLog();
            ARouter.openDebug();
        }

        ARouter.init(this);

        int myPid = android.os.Process.myPid();

        DataStoreManager.init(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            String processName = AppUtils.getProcessName(this, myPid);
            if (!BuildConfig.APPLICATION_ID.equals(processName)) {
                String processEndSuffix = StringUtils.getProcessEndfix(processName);
                if (TextUtils.isEmpty(processEndSuffix)) {
                    processEndSuffix = "other";
                }
                WebView.setDataDirectorySuffix(processEndSuffix);
            }
        }

        registerActivityLifecycleCallbacks(new AppActivityLifecycleCallbacks());

    }
}



public class AppActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

    @Override
    public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
        ActivityStackManager.add(activity);
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {

    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
        isAppBackground = false;//app回到前台
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {

    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
        isAppBackground = true;//app在后台
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
        ActivityStackManager.remove(activity);
    }
}

4、网络请求类  采用Retrofit网络请求

public class NetworkManager {

    private static String DEFAULT_BASE_URL = "http://api.xx.retrofit.com/";

    private CommonInterceptor commonInterceptor;

    private static final Map<String, Retrofit> retrofitMap = new HashMap<>();

    private CookieJar cookieJar;

    private static NetworkManager instance;

    private NetworkManager() {
    }

    public static NetworkManager getInstance() {
        if (instance == null) {
            instance = new NetworkManager();
        }
        return instance;
    }

    public void setDefaultDomain(String domain) {
        if (!TextUtils.isEmpty(domain)) {
            if (!domain.endsWith("/")) {
                domain += "/";
            }
            DEFAULT_BASE_URL = domain;
        }
    }

    public String getDefaultDomain() {
        return DEFAULT_BASE_URL;
    }

    public void setCommonParams(Map<String, String> commonParams) {
        commonInterceptor = new CommonInterceptor(commonParams);
    }

    public void setCookieJar(CookieJar cookieJar) {
        this.cookieJar = cookieJar;
    }

    private Retrofit buildRetrofit() {
        return buildRetrofit(DEFAULT_BASE_URL);
    }

    private Retrofit buildRetrofit(String baseUrl) {

        Retrofit retrofit;
        if (retrofitMap.containsKey(baseUrl)) {
            retrofit = retrofitMap.get(baseUrl);
        } else {

            OkHttpClient.Builder builder = new OkHttpClient.Builder();

            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(loggingInterceptor);

            if (commonInterceptor != null) {
                builder.addInterceptor(commonInterceptor);
            }

            if (cookieJar != null) {
                builder.cookieJar(cookieJar);
            }

            OkHttpClient okHttpClient = builder
                    .readTimeout(10, TimeUnit.SECONDS)
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .retryOnConnectionFailure(true)
                    .build();
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(okHttpClient)
                    .addConverterFactory(CustomGsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                    .build();

            retrofitMap.put(baseUrl, retrofit);
        }

        return retrofit;
    }

    public <T> T create(final Class<T> service) {
        return buildRetrofit().create(service);
    }

    public <T> T create(String baseUrl, final Class<T> service) {
        return buildRetrofit(baseUrl).create(service);
    }

}

5、网络请求interface 

public interface ListService {

    @GET("/Product/List")
    Observable<BaseResponse<ListCard>> getActList(@QueryMap Map<String, String> paramsMap);

}

//@GET("/Product/List") 接口名 
//ListCard实体类 可以通过RoboPOJOGenerator插件生成
//@QueryMap Map<String, String> paramsMap  是传入map参数
//如果传入string参数 可以这样写@Query("item_id") String item_id,@Query("page") int page




public class  ListCard {

	@SerializedName("image")
	public String image;

	@SerializedName("currPage")
	public Integer currPage;

	@SerializedName("pageTotal")
	public Integer pageTotal;

	@SerializedName("prePage")
	public Integer prePage;

	@SerializedName("list")
	public List<ProductCard> list;

	@SerializedName("title")
	public  String title;

	@SerializedName("desc")
	public  String desc;
}

6、创建ViewModel+LiveData

public class ListViewModel extends ViewModel {

    private ListService listService;
    private final SingleLiveData<ListCard> listData = new SingleLiveData<>();
    public MutableLiveData<Integer> listError = new MutableLiveData<>();


    public MutableLiveData<ListCard> getActListData(Context context, Map<String, String> paramsMap){

        if (listService == null) {
            listService = NetworkManager.getInstance().create(ListService.class);
        }
        listService.getActList(paramsMap)
                .compose(RxJavaHelper.observableIO2Main(context))
                .subscribe(new BaseObserver<ListCard>() {
                    @Override
                    public void onSuccess(ListCard result) {
                        listData.postValue(result);
                    }

                    @Override
                    public void onFailure(NetworkException e) {
                        listError.postValue(-1);
                    }
                });

        return listData;
    }
}

//因为数据需要分页加载  用SingleLiveData

public class SingleLiveData<T> extends MutableLiveData<T> {

    private final AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer<? super T> observer) {
        super.observe(owner, t -> {
            if (atomicBoolean.compareAndSet(true, false)) {
                observer.onChanged(t);
            }
        });
    }

    @Override
    public void postValue(T value) {
        atomicBoolean.set(true);
        super.postValue(value);
    }

}




public class RxJavaHelper {

    public static <T> ObservableTransformer<T, T> observableIO2Main(final Context context) {
        return upstream -> {
            Observable<T> observable = upstream.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
            return composeContext(context, observable);
        };
    }

    public static <T> ObservableTransformer<T, T> observableIO2Main(final RxFragment fragment) {
        return upstream -> upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).compose(fragment.<T>bindToLifecycle());
    }

    public static <T> FlowableTransformer<T, T> flowableIO2Main() {
        return upstream -> upstream
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    private static <T> ObservableSource<T> composeContext(Context context, Observable<T> observable) {
        if (context instanceof RxActivity) {
            return observable.compose(((RxActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
        } else if (context instanceof RxFragmentActivity) {
            return observable.compose(((RxFragmentActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
        } else if (context instanceof RxAppCompatActivity) {
            return observable.compose(((RxAppCompatActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
        } else {
            return observable;
        }
    }

}


/**
用于这种网络结构

{
	"code": "40000",
	"action": "",
	"message": "hhhh",
	"data": {}
}
*/


public class BaseResponse<T> {

    public int code;
    public String message;
    public String action;
    public T data;
}



public abstract class BaseObserver<T> implements Observer<BaseResponse<T>> {

    private final String TAG = "BaseObserver";

    public static final String ACTION_TOAST = "toast";

    @Override
    public void onSubscribe(@NonNull Disposable d) {
        LogUtils.i(TAG, "onSubscribe");
    }

    @Override
    public void onNext(@NonNull BaseResponse<T> baseResponse) {

        LogUtils.i(TAG, "onNext: message = %s ; code = %d", baseResponse.message, baseResponse.code);
        if (baseResponse.code == 0) {
            if (baseResponse.data == null) {
                LogUtils.e(TAG, "onNext: data is null");
                onFailure(new NetworkException(baseResponse.action, "data is null", NetworkException.CODE_DATA_NULL));
            } else {
                onSuccess(baseResponse.data);
            }
        } else {
            onFailure(new NetworkException(baseResponse.action, baseResponse.message, baseResponse.code));
        }

        onAction(baseResponse.action, baseResponse.message);
    }

    @Override
    public void onError(@NonNull Throwable e) {
        String errorMsg = NetworkError.handler(e);
        LogUtils.e(TAG, "onError: %s ; code = %d", errorMsg, NetworkException.CODE_ERROR);
        onFailure(new NetworkException("", errorMsg, -1));
    }

    @Override
    public void onComplete() {
        LogUtils.i(TAG, "onComplete");
    }

    public abstract void onSuccess(T result);

    public abstract void onFailure(NetworkException e);

    public boolean isToast(String action) {
        return TextUtils.equals(action, ACTION_TOAST);
    }

    protected void onAction(String action, String message) {
        if (isShowToast()) {
            showToast(action, message);
        }
    }

    /**
     * 是否显示toast ,默认不弹
     */
    protected boolean isShowToast() {
        return false;
    }

    private void showToast(String action, String message) {
        if (isToast(action)) {
            ToastUtils.showCenterToast(message);
        }
    }

}




public class NetworkException extends Exception {

    public static final int CODE_DATA_NULL = 80000; // 空数据
    public static final int CODE_ERROR = -99999;// 异常

    private String action;

    private String message;

    private final int errorCode;

    public int getErrorCode() {
        return errorCode;
    }

    public String getAction() {
        return action;
    }

    public String getMessage() {
        return message;
    }

    public NetworkException(String action, String message, int errorCode) {
        super(message);
        this.action = action;
        this.errorCode = errorCode;
        this.message = message;
    }
}

7、Activity请求接口

@Route(path = RoutePath.APP_ACT_LIST)
public class ListActivity extends BaseActivity {
    private String LOG_TAG = "ListActivity";
    private ActivityActListBinding binding;
    private int currPage = 1;
    private ListViewModel listViewModel;
    private ActListAdapter actListAdapter;
    private Map<String, String> paramsMap;


    @Override
    public View getBindingView() {
        binding = ActivityActListBinding.inflate(getLayoutInflater());
        return binding.getRoot();
    }

    @Override
    public void initPage() {
        StatusBarUtil.immersiveTitleView(binding.actHeadLayout);
        binding.rvActList.setLayoutManager(new LinearLayoutManager(this));
        binding.rvActList.addItemDecoration(new ActSpacesItemDecoration(this));
        paramsMap = getIntentParams();
        actListAdapter = new ActListAdapter(this);
        binding.rvActList.setAdapter(actListAdapter);
        actListViewModel = new ViewModelProvider(this).get(ListViewModel.class);
        requestActList(1);
        actListViewModel.actListError.observe(this, integer -> {
            //update ui
            LogUtils.e(LOG_TAG, "请求出错");

        });
        binding.actBack.setOnClickListener(view -> finish());
        binding.rvActList.setLoadMoreListener(() -> {
            currPage++;
            requestActList(currPage);
        });
    }


    private void requestActList(int page) {
        paramsMap.put("page",page+"");
        actListViewModel.getActListData(this,paramsMap).observe(this, actListCard -> {
            //update ui
            LogUtils.e(LOG_TAG, "请求成功");
            if (actListCard != null) {
                binding.bigActTitle.setText(actListCard.title);
                binding.smallActTitle.setText(actListCard.desc);

                boolean hasMore = false;
                currPage = actListCard.currPage;
                if (currPage == 1) {
                    actListAdapter.setData(actListCard.list);
                    Log.d(LOG_TAG, "setData" + currPage);
                } else {
                    actListAdapter.addData(actListCard.list);
                    Log.d(LOG_TAG, "addData" + currPage);
                }
                hasMore = currPage < actListCard.pageTotal;
                actListAdapter.setHasMore(hasMore);
                binding.rvActList.notifyMoreFinish(hasMore);
            }
        });
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Retrofit、RxJava和LiveDataAndroid开发中常用的三个库,用于提升网络请求和数据响应的效率和易用性。 首先来说说Retrofit,它是Square公司开发的一个网络请求库,可以简化HTTP请求的过程。具体来说,Retrofit通过注解方式定义API接口,支持多种数据格式的解析,如JSON、XML等,提供了丰富的请求方法和参数,可以使用线程池进行并发请求。Retrofit可以根据接口的定义,自动将HTTP请求转化为对应的Java方法调用,并将服务器返回的数据转化为Java对象。通过Retrofit,我们可以轻松地进行网络请求,提高了开发效率。 然后是RxJava,RxJava基于观察者模式和函数式编程思想,是一个强大的异步编程库。它提供了丰富的操作符和线程调度器,可以轻松地处理复杂的异步任务。通过RxJava,我们可以通过链式调用的方式组合多个异步操作,将它们串行或并行执行,还可以添加错误处理和重试机制。RxJava可以与Retrofit配合使用,通过它的观察者模式,可以实现将网络请求结果流式化,使得异步任务的处理更加简洁和灵活。 最后是LiveDataLiveData是Google在Android Architecture Components中引入的一个观察者模式类。LiveData具有生命周期感知能力,可以根据Activity或Fragment的生命周期自动管理数据的更新和释放,避免了内存泄漏和空指针异常。LiveData还支持后台线程发送数据,可以与RxJava搭配使用来实现异步数据更新。LiveData使得数据的处理更加安全可控,为开发者提供了一种便捷的方式来更新UI和响应数据变化。 综上所述,Retrofit提供了简洁的网络请求接口,RxJava提供了强大的异步编程能力,LiveData提供了响应式的数据更新机制。它们三者的结合使得网络请求和数据响应的处理更加简单高效,提高了开发效率和代码质量。 ### 回答2: Retrofit、RxJava和LiveData是三种在Android开发中经常使用的库,用于进行网络请求和响应处理、异步操作和数据监听。 Retrofit是一种用于处理网络请求的库,它能够将网络请求与后台API进行连接,通过定义接口和请求方法,方便地进行网络请求和处理响应结果。Retrofit通过注解的方式定义网络请求方式、URL等信息,结合Gson等库进行数据解析,使得网络请求变得简单高效。 RxJava是一种响应式编程库,它能够方便地实现异步操作和事件流处理。通过使用Observables(被观察者)和Subscribers(观察者),我们可以将异步任务和数据流以扁平化的方式进行处理。RxJava提供了丰富的操作符,能够方便地实现异步请求、线程切换、数据过滤、转换等功能,使得代码逻辑更加简洁和可读。 LiveData是一种用于在Android应用中实现数据监听的库。LiveData可以感知生命周期并自动更新界面数据,能够保证数据的一致性和UI的正确性。LiveData可以与ViewModel结合使用,通过观察数据的变化来更新UI。与传统的观察者模式相比,LiveData具有更丰富的功能,例如避免内存泄漏、解决配置变化等问题。 综上所述,Retrofit是用于处理网络请求的库,通过简单高效的方式连接后台API;RxJava是用于实现异步操作和事件流处理的库,提供丰富的操作符;LiveData是用于在Android应用中实现数据监听的库,能够自动更新界面数据。这三个库的结合使用可以更加方便地进行网络请求、数据处理和UI更新。 ### 回答3: Retrofit,RxJava和LiveData都是在Android开发中常用的工具或库。它们各自有着不同的功能和用途。 Retrofit是一个用于网络请求的库,它能够更方便地进行网络通信。通过Retrofit,我们可以定义网络请求的接口,定义请求的方法和参数,并且可以方便地处理返回的数据。Retrofit底层使用了OkHttp库,可以实现网络请求的异步调用和线程切换,提高了网络请求的效率和稳定性。 RxJava是一个基于观察者模式的库,它提供了一套丰富的函数式编程接口,能够处理异步事件流。通过RxJava,我们可以轻松地创建、转换和操作Observable(被观察者),并且可以使用丰富的操作符来处理数据的过滤、变换和组合。RxJava还支持线程切换和错误处理,能够更好地处理异步任务。 LiveDataAndroid架构组件库中的一个组件,它用于在数据发生变化时通知观察者。LiveData可以感知Activity或Fragment的生命周期,并且会将数据更新通知给观察者。与传统的观察者模式相比,LiveData具有生命周期感知能力,可以避免内存泄漏和空指针异常。LiveData还支持数据的多个观察者,可以实现多个界面或组件之间的数据共享。 综上所述,Retrofit用于网络请求,RxJava用于处理异步事件流,LiveData用于在数据变化时通知观察者。它们在Android开发中各有不同的应用场景,能够提高开发效率和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值