当前位置: 首页 > wzjs >正文

做网站的图片用什么格式淘宝推广软件哪个好

做网站的图片用什么格式,淘宝推广软件哪个好,做网站广告怎么做,百度搜索页面MVVM 架构详解 核心组件:ViewModel 和 LiveData 在 Android 中,MVVM 架构主要借助 ViewModel 和 LiveData 来实现。ViewModel 负责处理业务逻辑,而 LiveData 则用于实现数据的响应式更新。 ViewModel 的源码分析 ViewModel 的核心逻辑在 …

MVVM 架构详解

核心组件:ViewModel 和 LiveData

在 Android 中,MVVM 架构主要借助 ViewModel 和 LiveData 来实现。ViewModel 负责处理业务逻辑,而 LiveData 则用于实现数据的响应式更新。

ViewModel 的源码分析

ViewModel 的核心逻辑在 ViewModelStore 类中。ViewModelStore 是一个存储 ViewModel 的容器,内部使用 HashMap 来存储不同的 ViewModel 实例。以下是 ViewModelStore 的关键代码:

public class ViewModelStore {private final HashMap<String, ViewModel> mMap = new HashMap<>();final void put(String key, ViewModel viewModel) {ViewModel oldViewModel = mMap.put(key, viewModel);if (oldViewModel != null) {oldViewModel.onCleared();}}final ViewModel get(String key) {return mMap.get(key);}public final void clear() {for (ViewModel vm : mMap.values()) {vm.onCleared();}mMap.clear();}
}

ViewModel 利用 ViewModelStore 保证在配置变更(如屏幕旋转)时数据不丢失,并且将业务逻辑与 ActivityFragment 分离,提高了代码的可维护性和可测试性。

LiveData 的源码分析

LiveData 基于观察者模式,通过 observe 方法添加观察者,当数据变化时,会调用 Observer 的 onChanged 方法更新 UI。

与 MVC 架构对比

MVC 架构的问题

在 MVC 架构中,Activity 既充当 View 又充当 Controller。在 Android 中,Activity 继承自 AppCompatActivity,其源码中包含大量视图初始化和事件处理代码,使得 Activity 变得复杂。例如:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button).setOnClickListener(v -> {// 处理点击事件});}
}

与 MVVM 相比,MVC 没有明确的职责划分,导致代码耦合度高,难以维护和扩展。

与 MVP 架构对比

MVP 架构的特点

MVP 中 Presenter 与 View 通过接口交互。Presenter 持有 View 接口的引用,在更新视图时调用接口方法。以下是一个简单的示例:

// View 接口
public interface MainView {void showData(String data);
}// Presenter 类
public class MainPresenter {private MainView view;public MainPresenter(MainView view) {this.view = view;}public void loadData() {// 模拟加载数据String data = "Hello, MVP!";view.showData(data);}
}

而 MVVM 采用数据绑定,ViewModel 无需持有 View 的引用,降低了耦合度,使得代码更加灵活和易于维护。

面试扩展:

MVVM 架构与其他架构区别

  1. 请详细阐述 MVVM、MVC 和 MVP 架构在数据绑定机制上的差异,并说明这种差异如何影响代码的可维护性和扩展性。
    回答

    • MVVM:在 Android 中借助 LiveData 实现数据绑定,以 LiveData 源码为例,它基于观察者模式,通过 observe 方法添加观察者,内部维护 mVersion 和 ObserverWrapper 的 mLastVersion 来控制数据分发。数据变化时,LiveData 会遍历观察者调用 onChanged 方法更新 UI,使得 View 和 ViewModel 之间的数据同步自动化,减少手动更新代码,提高可维护性与扩展性。例如在复杂 UI 界面中,数据更新无需在多处手动操作视图。
    • MVC:如在 Android 里 Activity 常兼具 View 和 Controller 职责,在 Activity 源码中,大量视图初始化和事件处理代码混杂,在更新视图时需手动在 Controller 部分(如 Activity 中的业务逻辑代码)编写更新视图的代码,这导致代码耦合度高,可维护性差。例如一个界面有多个视图需更新,代码中会有多处重复的视图更新逻辑,不利于扩展新功能。
    • MVP:Presenter 通过接口与 View 交互,更新视图时 Presenter 手动调用 View 接口方法。从代码结构看,Presenter 持有 View 引用,若业务逻辑复杂,Presenter 会变得臃肿,可维护性降低。且当 View 层变化时,Presenter 中调用 View 接口方法的代码也需大量修改,扩展性不佳。比如更换了视图框架,Presenter 中更新视图的方法基本都要调整。
  2. 从架构组件的生命周期角度,分析 MVVM 与 MVP 架构的不同。
    回答

    • MVVM:ViewModel 的生命周期由 ViewModelStore 和 ViewModelProvider 管理。ViewModelProvider 从 ViewModelStore 中创建或获取 ViewModel 实例,在配置变更(如屏幕旋转)时,ViewModel 实例不销毁,保证数据存储。而 LiveData 具有生命周期感知能力,通过 LifecycleOwner 控制观察者的注册与注销,只有当 LifecycleOwner 处于活跃状态(如 STARTED 或 RESUMED)时,观察者才会接收数据更新,避免内存泄漏等问题。
    • MVP:Presenter 与 View 通过接口交互,Presenter 持有 View 引用。但 Presenter 本身没有很好的生命周期管理机制,在配置变更时,若不妥善处理,Presenter 可能会持有旧的 View 引用,导致内存泄漏。例如在屏幕旋转时,若没有正确处理 Presenter 与 View 的关系,可能会出现空指针异常等问题。

LiveData 数据倒灌的源码级别分析

数据倒灌的原因

LiveData 内部维护了一个 mVersion 和 START_VERSIONmVersion 表示 LiveData 数据的版本号,每次数据更新时 mVersion 会递增。ObserverWrapper 是 Observer 的包装类,其中的 mLastVersion 记录了观察者最后一次接收到数据的版本号。

// LiveData 关键代码
private static abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;ObserverWrapper(Observer<? super T> observer) {mObserver = observer;}// ...
}

当新的观察者注册时,LiveData 会检查 mLastVersion 和 mVersion,如果 mLastVersion 小于 mVersion,则会将数据发送给观察者,从而导致数据倒灌。

解决方法原理

以 SingleLiveEvent 为例,它通过一个标志位 mPending 来控制数据是否已被消费。

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;import java.util.concurrent.atomic.AtomicBoolean;public class SingleLiveEvent<T> extends MutableLiveData<T> {private final AtomicBoolean mPending = new AtomicBoolean(false);@Overridepublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {super.observe(owner, t -> {if (mPending.compareAndSet(true, false)) {observer.onChanged(t);}});}@Overridepublic void setValue(T value) {mPending.set(true);super.setValue(value);}@Overridepublic void postValue(T value) {mPending.set(true);super.postValue(value);}
}

当数据更新时,mPending 设为 true,观察者接收到数据后将其设为 false,确保数据只被消费一次。

面试扩展:

  1. 请描述 LiveData 数据倒灌产生的原因,并给出至少两种基于源码层面的解决方案。
    回答
    • 原因:从 LiveData 源码看,它内部维护 mVersion 代表数据版本号,每次数据更新 mVersion 递增,ObserverWrapper 中的 mLastVersion 记录观察者最后接收数据版本号。新观察者注册时,若 mLastVersion 小于 mVersion,就会接收数据,导致数据倒灌。
    • 解决方案
      • SingleLiveEvent:它通过 AtomicBoolean 类型的 mPending 标志位控制数据消费。数据更新时,mPending 设为 true,观察者接收数据后设为 false,保证数据只被消费一次。从其源码实现可知,在 observe 方法中判断 mPending 状态决定是否通知观察者。
      • 自定义 LiveData 包装类:在自定义包装类中添加版本号或标记位。如在包装类中维护一个 AtomicInteger 类型的版本号,每次数据更新时版本号递增,在 observe 方法中,观察者接收数据后记录当前版本号,下次数据更新时对比版本号,若相同则不通知,从而避免数据倒灌。

ViewModel 对 UI 数据管理的源码级别分析

数据存储与生命周期管理

ViewModel 的生命周期由 ViewModelStore 和 ViewModelProvider 管理。ViewModelProvider 负责创建和获取 ViewModel 实例,它会先从 ViewModelStore 中查找是否存在该 ViewModel 实例,如果存在则直接返回,不存在则创建新的实例。

// ViewModelProvider 关键代码
public class ViewModelProvider {private final Factory mFactory;private final ViewModelStore mViewModelStore;public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {mFactory = factory;mViewModelStore = store;}@NonNull@MainThreadpublic <T extends ViewModel> T get(@NonNull Class<T> modelClass) {String canonicalName = modelClass.getCanonicalName();if (canonicalName == null) {throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");}return get(DEFAULT_KEY + ":" + canonicalName, modelClass);}@NonNull@MainThreadpublic <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {ViewModel viewModel = mViewModelStore.get(key);if (modelClass.isInstance(viewModel)) {//noinspection uncheckedreturn (T) viewModel;} else {//noinspection StatementWithEmptyBodyif (viewModel != null) {// TODO: log a warning.}}viewModel = mFactory.create(modelClass);mViewModelStore.put(key, viewModel);//noinspection uncheckedreturn (T) viewModel;}
}

这样,在配置变更时,ViewModel 实例不会被销毁,保证了数据的存储。

数据更新与通知

ViewModel 通常使用 LiveData 来存储和通知 UI 数据的变化。当 ViewModel 中的数据更新时,调用 LiveData 的 setValue 或 postValue 方法,LiveData 会遍历所有观察者并调用其 onChanged 方法。

// LiveData 关键代码
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection uncheckedobserver.mObserver.onChanged((T) mData);
}

通过这种方式,ViewModel 实现了对 UI 数据的管理和更新通知。

面试扩展:

  1. 从源码角度分析 ViewModel 如何确保在配置变更时 UI 数据不丢失,以及如何与 LiveData 协作更新 UI。
    回答
    • 配置变更时数据不丢失ViewModel 借助 ViewModelStore 和 ViewModelProvider 实现。ViewModelStore 内部用 HashMap 存储 ViewModel 实例,ViewModelProvider 在创建或获取 ViewModel 实例时,先从 ViewModelStore 查找,若存在则返回,不存在才创建新实例。例如在屏幕旋转等配置变更时,ViewModel 实例得以保留,确保 UI 数据不丢失。
    • 与 LiveData 协作更新 UIViewModel 通常使用 LiveData 存储和通知 UI 数据变化。当 ViewModel 中数据更新,调用 LiveData 的 setValue 或 postValue 方法,LiveData 会遍历观察者调用 considerNotify 方法,在 considerNotify 方法中判断观察者状态和版本号等条件后,调用观察者的 onChanged 方法通知 UI 更新。
http://www.dtcms.com/wzjs/149802.html

相关文章:

  • 一键免费做网站广告投放策略
  • 东莞大岭山网站建设西安网站seo外包
  • 甘肃网站建设费用模板建网站价格
  • 上海电子通科技网站建设青岛百度seo代理
  • wordpress 页头设置网站优化排名易下拉排名
  • 关于学院网站建设的通知百度导航2023年最新版
  • 贵阳网页设计优化网站搜索排名
  • php怎么做视频网站个人怎么做推广
  • 泉州有专门帮做网站的吗郑州网站推广技术
  • 哪些网站可以用gif做头像软文推广代理
  • 建收费网站搜索引擎优化seo应用
  • b2c购物网站开发alexa排名
  • 个人网站是啥硬件优化大师
  • 做企业网站需要购什么温岭网络推广
  • 微网站建设市场关键词搜索排名推广
  • 哪里有网站制作公司日营销策划方案ppt范文
  • 微信做单页的网站百度推广客户端电脑版
  • 创建购物网站搜索引擎关键词广告
  • 排名好的郑州网站建设网站快速优化排名排名
  • 做网站帮京东卖东西怎么合作北京线上教学
  • 网站建设需要找工信部吗seo点击
  • 网站建设制作方式有哪些网络推广费用计入什么科目
  • 物流企业网站建设步骤数据分析网站
  • 网站建设未完成短视频营销的发展趋势
  • wordpress外贸商城主题东莞网站建设优化诊断
  • 瑞安企业做网站网络广告营销典型案例
  • 货运公共平台市场推广seo职位描述
  • 资讯网站老哥们给个关键词
  • 网站注册转化率搜索引擎优化seo的英文全称是
  • 做网站语言搜索引擎的四个组成部分及作用