关于MockView中“Mock“编程思想的个人理解及实践
Posted 静水流深zz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于MockView中“Mock“编程思想的个人理解及实践相关的知识,希望对你有一定的参考价值。
MockView
MockView 很早之前就有接触过,虽然阅读了大佬的文章:Why Mocking Matters,但是并没有很好地理解。随着开发经验的不断积累,以及在flutter_hybird_webview 跨进程渲染的实践中,模块跨进程迁移
的开发过程中对Mock
有了更进一步的理解,在此分享一下本菜鸡的理解。
介绍
MovkView
位于com.android.layoutlib.bridge
包下,并继承自FrameLayout
,同时禁止添加其它子view
,内部代码如下:
public class MockView extends FrameLayout
private final TextView mView;
///...省略构造函数
// Only allow adding one TextView.
@Override
public void addView(View child)
if (child == mView)
super.addView(child);
@Override
public void addView(View child, int index)
if (child == mView)
super.addView(child, index);
@Override
public void addView(View child, int width, int height)
if (child == mView)
super.addView(child, width, height);
@Override
public void addView(View child, ViewGroup.LayoutParams params)
if (child == mView)
super.addView(child, params);
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params)
if (child == mView)
super.addView(child, index, params);
android
中使用这个类的地方也不多,如webview
,surface view
等,他们比较突出的特点就是跨sdk
、跨进程
,这里我以webview
谈一下个人的理解。
Mock编程思维的个人认识:webview
早期版本的webview
继承自AbsoluteLayout
(见 WebView | Android Developers),在最近的android(27或者28)
版本才继承自MockView
。
引起webview
继承变化的原因,我认为大致有以下几点:
-
AbsoluteLayout
过期了。 -
随着
app
的发展,对于webview
在表现上有了更复杂的需求,这点从AbsoluteLayout
的注释可见一斑。
/*
... Absolute layouts are less flexible and harder to maintain
than other types of layouts without absolute positioning.
在布局上的灵活性和操控性相对较差。
*/
public class AbsoluteLayout extends ViewGroup
...
-
更复杂的测试和协同开发需求,这个参见大佬的文章和当下app的规模。
-
webview
的renderer
从android(26)
开始,工作在独立的进程,进一步讲就是沙箱化
。
Starting in Oreo (API 26) WebView has a single out-of-process renderer
(we sometimes refer to this as "multiprocess mode"). This is enabled
for high-memory devices (low-memory devices still use an in-process renderer
as before).
The out-of-process renderer is enabled by a new Android API (`android:externalService`),
to create sandboxed processes which run in the *embedding app's context* rather than
the WebView provider's context.
Chromium
本身含有这个机制,只是Android-Chromium
(来源于Chromium)可能是由于早期设备资源不足才无法支持此机制(个人推测)。
综合上述几点,我认为之所以做如此改动,是因为模块
达到一定复杂度和特征后,需要结合其特征进行进一步
的模型化(这同时也是一种对外约束)。
通过对`View`的`Mock`表明其在`ui`系统中的身份特性
通过对`addChild()`的禁止,可以表明渲染的独立性,以及对外的约束
通过整体模型化,可以满足跨域/协同开发的联调及测试问题。
Mock编程思维的实践
这里我介绍一下在flutter_hybird_webview和日常开发中的实践。
flutter_hybird_webview的Channel Mock
在对Flutter的webview
插件中的android模块
进行跨进程迁移
的过程中,需要对模块的通信方式进行分析,并对通信点(或者说它们的通信接口模型)进行Mock
。 这样即保证了最小迁移工作量,同时因为遵从原通信模型(对修改封闭,对拓展开放),而确保了向后兼容。
在Flutter中webview
插件的原通信方式大致如下图:
迁移后的通信方式大致如下:
这样,整个迁移过程就类似于平移了。
日常开发中的应用
在日常开发中,会有一些功能极为复杂的页面,如购物车,它可能包含:
- 各种路由跳转逻辑
- 复杂的交互逻辑
- 复杂的数据显示逻辑
- 缓存、数据封包传递 等等
在MVVM
架构下,上述功能的累加及不断地迭代会导致vm
异常臃肿。因此,我们会对vm
进行下沉式的拆分,这样不仅代码结构清晰,且更精细的控制也带来了更高的性能。与此同时还可以基于ui/业务逻辑
对数据模型
进行进一步的Mock
,这样不仅可以进一步优化代码结构,提高开发自测效率,还可以平抑掉迭代过程中数据实体或逻辑变化对vm
内部结构的影响。
以上就是我对Mock
的浅见及在开发过程中的实践,如有不足或错误的地方还请指出,谢谢阅读。
其他文章
Flutter在Android平台上启动时,Native层做了什么?
以上是关于关于MockView中“Mock“编程思想的个人理解及实践的主要内容,如果未能解决你的问题,请参考以下文章
关于阅读java编程思想和effective java的一些看法
Android MVP-编程思想5(如何处理多个P层的问题?)