Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一周安卓开发问题汇总(三) #134

Open
soapgu opened this issue Apr 13, 2022 · 0 comments
Open

一周安卓开发问题汇总(三) #134

soapgu opened this issue Apr 13, 2022 · 0 comments
Labels
problem problem or trouble 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Apr 13, 2022

  • 前言

老规矩,一周继续对本周的开发进行总结和提炼,希望能对以后的开发避雷

  • Error and Failure retrofit2 mock

目前进入对接Restful后台协议阶段。
后台服务虽然还在开发,但是协议已经基本明确了。所以我们完全可以通过retrofit2 mock的方式模拟后台真实数据,写出“接近”真实的后台对接代码。

无意之中,竟然报出错误了。

E/space365: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
E/space365: │ Thread: main
E/space365: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
E/space365: │ MobileHomeViewModel$$ExternalSyntheticLambda1.accept  (null:4)
E/space365: │    MobileHomeViewModel.lambda$load$1$com-space365-mobile-viewmodels-MobileHomeViewModel  (MobileHomeViewModel.java:78)
E/space365: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
E/space365: │ load home page error : retrofit2.mock.MockRetrofitIOException: Failure triggered by MockRetrofit's NetworkBehavior
E/space365: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────

图片
奇怪了。都是“造假”了怎么还造出错误来了

经过一番探索,终于明天了原作者的 用心良苦
图片

  • 全局配置 NetworkBehavior

第一次用NetworkBehavior只是无脑new出来用了,完全看出他真正的威力
看下他的默认配置

  private static final int DEFAULT_DELAY_MS = 2000; // Network calls will take 2 seconds.
  private static final int DEFAULT_VARIANCE_PERCENT = 40; // Network delay varies by ±40%.
  private static final int DEFAULT_FAILURE_PERCENT = 3; // 3% of network calls will fail.
  private static final int DEFAULT_ERROR_PERCENT = 0; // 0% of network calls will return errors.

默认2秒的网络延时,±40%的网络随机抖动, 3%的失败率,后台报错失败率也能设。
这样让我们在体验上能更“真”一点
另外后端以及网络的Exception还能自定义factory,很体贴了。
让我们能体验感上接近真实,实际上还能预防异常问题处理的健壮能力

  • 深入到协议层的BehaviorDelegate

BehaviorDelegate我也要重新认识了。首先以前我的用法就是直接把mock 的数据给response出来,这只是他的“基本职能”。
如果NetworkBehavior是retrofit2 mock的“总指挥”
那么BehaviorDelegate就是restful协议层的“政委”
图片
他“负责”具体协议mock的实施

让我们先回顾了我常用的方法的源码

public T returningResponse(@Nullable Object response) {
    return returning(Calls.response(response));
  }

这里看Object response不是真正的核心
真正的核心是Calls

public static <T> Call<T> response(@Nullable T successValue) {
    return new FakeCall<>(Response.success(successValue), null);
  }

  public static <T> Call<T> response(Response<T> response) {
    return new FakeCall<>(response, null);
  }

  /** Creates a failed {@link Call} from {@code failure}. */
  public static <T> Call<T> failure(IOException failure) {
    // TODO delete this overload in Retrofit 3.0.
    return new FakeCall<>(null, failure);
  }

  /**
   * Creates a failed {@link Call} from {@code failure}.
   *
   * <p>Note: When invoking {@link Call#execute() execute()} on the returned {@link Call}, if {@code
   * failure} is a {@link RuntimeException}, {@link Error}, or {@link IOException} subtype it is
   * thrown directly. Otherwise it is "sneaky thrown" despite not being declared.
   */
  public static <T> Call<T> failure(Throwable failure) {
    return new FakeCall<>(null, failure);
  }

主要亮点是Throwable ,这样我可以在Mock中制造人工的意外来提前测试app的健壮性,这是非常有意义的。
也是TDD方向的重点

当然目前阶段,我可以先把FAILURE_PERCENT设为0.

    @Singleton
    @Provides
    public static MockRetrofit provideMockRetrofit(Retrofit retrofit){
        NetworkBehavior behavior = NetworkBehavior.create();
        behavior.setFailurePercent(0);
        return new MockRetrofit.Builder(retrofit)
                .networkBehavior(behavior)
                .build();
    }
  • 相关链接

  • 相关issues

  • 去除MVVM绑定Fragment的警告

每次开启程序的时候,Logcat总会冒出一些奇怪的警告
2022-04-13 21:08:38.117 13637-13637/com.space365.app W/DataBinding: Setting the fragment as the LifecycleOwner might cause memory leaks because views lives shorter than the Fragment. Consider using Fragment's view lifecycle
图片
这次一定要把他收拾掉

 @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.viewModel =  new ViewModelProvider(this.provideViewModelStoreOwner()).get(classOfVM);
        ViewDataBinding binding = DataBindingUtil.inflate( inflater , layoutId , container ,false );
        binding.setVariable( this.variableId , this.viewModel );
        binding.setLifecycleOwner(this.getViewLifecycleOwner());
        for( Pair<Integer, Object> each : getExtraVariableSource() ){
            binding.setVariable( each.first , each.second );
        }
        return binding.getRoot();
    }

解决也不复杂,把binding.setLifecycleOwner(this) 改成 binding.setLifecycleOwner(this.getViewLifecycleOwner())
现在想想也是Fragment其实和View并不是一个整体

  • ViewModel最“长命”

  • View最“短命”

  • Fragment其实装配人员,介于两者之间

  • Fragment和Activity生命周期有细微差别,Activity里面LifecycleOwne设this没毛病也是官挡本来就这样写的

  • 关于List集合的addAll方法报错UnsupportedOperationException

这个报错也确实奇怪,怎么List就突然不能加数据了那
后来问题集中在两个点,Collections.singletonList(T o) 和Arrays.asList( para ... )
为啥他们制造的集合就不能加数据那
还是翻源码吧
图片
一看这个size还是锁死的嘛
再看基类
图片
就是不实现add就是默认报出UnsupportedOperationException的异常。
一开始这两个api就是产出“固定数组”的。
源码和Exception都能对上,破案结束

  • Glide进阶,实现多种变化

这次我需要把图片裁剪为方形并加上固定尺寸的圆角。怎么实现那

 RequestOptions options = new RequestOptions()
                .override(80,80)
                .transform( new CenterCrop(), new RoundedCorners(12) );

如果我先RoundedCorners,这个图的圆角就几乎看不到了。
所以我的顺序是先裁剪在加导角
图片

@soapgu soapgu changed the title Error and Failure retrofit2 mock 一周安卓开发问题汇总(三) Apr 16, 2022
@soapgu soapgu added 安卓 安卓 problem problem or trouble labels Apr 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
problem problem or trouble 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant