1、build.gradle添加依赖
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//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
复制代码
1
2
3
4
5
6public class BaseActivity extends RxAppCompatActivity { } public class BaseFragment extends RxFragment { }
3、Application增加registerActivityLifecycleCallbacks 可以监听到 Activity 的状态,从而可以判断 APP 是否在前台或者后台等
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82public 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网络请求
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95public 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217public 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请求接口
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64@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); } }); } }
最后
以上就是负责缘分最近收集整理的关于Android Retrofit+LiveData+ViewModel架构的全部内容,更多相关Android内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复