Android App Arch
作者:互联网
Android Arch
-
工程模块
-
界面导航
简要说明
使用Jetpack Nav库采用单Activity架构模式
-
UI复用(Fragment)
-
Activity之间跳转动画的问题。界面跳转会出现状态栏闪现
-
Activity之间共享数据问题
要使用单例(Application Scope)来保存数据
而单Activity可通过共享的ViewModel来传递数据。
-
向Fragment传递数据有时候会特别痛苦
-
Navigation UI库便于处理BotNavView,NavDrawer等
启动页只处理权限申请相关,权限申请可选方案:
https://codix.io/repo/27043/similar
-
Nammu
-
Dexter
-
RxPermissions
-
PermissionsDispatcher
最终选用了RxPermission,放弃使用PermissionDispatcher,与Dagger有兼容问题(使用了@Deprecated method)
DialogFragment作为全局的弹框界面单独拎了出来,优劣有待考证。
技术细节
- Fragment之间的数据传递
- Fragment与Activity之间的数据传递
- Activity之间的数据传递
详情可参阅Android官方文档:https://developer.android.com/guide/fragments/communicate
-
-
数据流
简要说明
-
技术栈
LiveData
+RxJava
+Hilt
+Dagger
+Retrofit
+OkHttp
-
非特定情况下限定使用以上三种Layout,参阅图片中说明1.2.3条
-
控件实现方案与要点参阅以下
-
建议只需使用ViewBinding
-
ViewBinding 是 DataBinding的子集(ViewBinding能做的事DataBinding都能做,反过来不行)
-
ViewBinding更高效,编译速度更快(Main Advantage)编译包体积更小
-
使用了DataBinding没必要再使用viewbinding
-
ViewBinding不需要在布局文件嵌套一层TAG
<layout>
-
-
Theme
设计人员可使用以下工具参阅:
https://material.io/resources/color/#!/?view.left=0&view.right=0
应用主题相关
是一个自定义Resource的集合(theme attribute),可被layout、style等引用。theme的attribute不限定于一个控件的属性,这些值实在整个应用中贯穿使用,
是应用视图的一个抽象集合,便于更换整个应用的主题,类似于一个interface,然后在不同主题下实现不同的属性配置。
-
Style
对同一类别控件封装管理
view attribute的集合:key只能为控件定义好的属性名称,好处是可对同一类别控件的属性封装后可复用,便于统一管理,只对当前控件有效
技术要点
-
第三方lib callback回调如何转RxJava Observable
使用
ObservableEmitter
public Observable<LoginResponse> handleLogin(String phone, String password) { logger.d(TAG, "do Phone " + phone + " Pwd Login"); if (!sdkConfigured) { //should never happen throw new UnsupportedOperationException("CTChat SDK Not Configured Yet"); } return Observable.create(emitter -> { AccountManager.login(application, phone, password, new ObservableLoginCallback(emitter)); }); private final class ObservableLoginCallback implements LoginCallback { @NonNull private final ObservableEmitter<LoginResponse> emitter; public ObservableLoginCallback(@NonNull ObservableEmitter<LoginResponse> emitter) { this.emitter = emitter; } @Override public void onLoginSuccess(boolean needChangePassword) { logger.d(TAG, "on login success -> needChangePwd:" + needChangePassword); emitter.onNext(new LoginResponse(SUCCESS, "")); emitter.onComplete(); } @Override public void onLoginError(int errCode) { logger.w(TAG, "on login err -> code:" + errCode); LoginResponse loginResponse = new LoginResponse(getLoginResponseCode(errCode), ""); emitter.onNext(loginResponse); emitter.onComplete(); } } }
-
使用RxJava merge操作符进行本地数据与远端数据依次告知UI
-
跟随Fragment声明周期的变量AutoClearedValue
public class AutoClearedValue<T> { private T value; public AutoClearedValue(@NotNull Fragment fragment, T value) { this.value = value; fragment.getLifecycle().addObserver(new DefaultLifecycleObserver() { @Override public void onCreate(@NonNull LifecycleOwner owner) { fragment.getViewLifecycleOwnerLiveData().observe(fragment, viewLifecycleOwner -> { viewLifecycleOwner.getLifecycle().addObserver(new DefaultLifecycleObserver() { @Override public void onDestroy(@NonNull LifecycleOwner owner) { AutoClearedValue.this.value = null; } }); }); } }); } public T get() { return value; } }
-
DI(依赖注入)
需要单独写文档
-
标签:控件,Fragment,App,value,emitter,new,Android,Arch,public 来源: https://www.cnblogs.com/kelisi-king/p/14837466.html