ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android App Arch

2021-06-01 18:02:27  阅读:269  来源: 互联网

标签:控件 Fragment App value emitter new Android Arch public


Android Arch

  1. 工程模块

    Module

  2. 界面导航

    UI Flow

    简要说明

    使用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

  3. 数据流

    DataFlow

    简要说明

    • 技术栈

      LiveData + RxJava + Hilt + Dagger + Retrofit + OkHttp

    • 非特定情况下限定使用以上三种Layout,参阅图片中说明1.2.3条

      Layout 渲染效率对比结果

    • 控件实现方案与要点参阅以下

      https://material.io/components?platform=android

    • 建议只需使用ViewBinding

      PreferenceActivity 还不支持databinding

      • 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有