IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Retrofit+LiveData+ViewModel架构 -> 正文阅读

[移动开发]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);
            }
        });
    }
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:19:29  更:2021-08-03 11:21:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 3:35:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码