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

生物科技企业网站做的比较好的网站seo 教程

生物科技企业网站做的比较好的,网站seo 教程,国外手机模板网站,游戏外包公司要不要去文章目录 ViewModel实现ViewModelViewModel的生命周期在Fragments间分享数据ViewModel和SavedInstanceState对比ViewModel原理ViewModel与AndroidViewModel ViewModel Android系统提供控件#xff0c;比如Activity和Fragment#xff0c;这些控件都是具有生命周期方法#x… 文章目录 ViewModel实现ViewModelViewModel的生命周期在Fragments间分享数据ViewModel和SavedInstanceState对比ViewModel原理ViewModel与AndroidViewModel ViewModel Android系统提供控件比如Activity和Fragment这些控件都是具有生命周期方法这些生命周期方法被系统调用。在数据使用上有两个问题 当这些控件被销毁或者被重建的时候如果数据保存在这些对象中那么数据就会丢失。比如在一个界面保存了一些用户信息当界面重新创建的时候就需要重新去获取数据。当然了也可以使用控件自动再带的方法在onSaveInstanceState方法中保存数据在onCreate中重新获得数据但这仅仅在数据量比较小的情况下。如果数据量很大这种方法就不能适用了。 另外一个问题就是经常需要在Activity中加载数据这些数据可能是异步的因为获取数据需要花费很长的时间。那么Activity就需要管理这些数据调用否则很有可能会产生内存泄露问题。最后需要做很多额外的操作来保证程序的正常运行。 同时Activity不仅仅只是用来加载数据的还要加载其他资源做其他的操作最后Activity类变大就是我们常讲的上帝类。也有不少架构是把一些操作放到单独的类中比如MVP就是这样创建相同类似于生命周期的函数做代理这样可以减少Activity的代码量但是这样就会变得很复杂同时也难以测试。 ViewModel是专门用于存放应用程序页面所需的数据。ViewModel将页面所需的数据从页面中剥离出来页面只需要处理用户交互和展示数据。 Viewmodel解决两个问题: 数据的变更与view隔离也就是解耦开发者不需要额外去关心因为屏幕旋转带来的数据恢复问题 实现ViewModel ViewModel是一个抽象类其中只有一个onCleared()方法。当ViewModel不再被需要即与之相关的Activity都被销毁时onCleared()方法会被系统调用。我们可以在该方法中执行一些资源释放的相关操作。(注意由于屏幕旋转而导致的Activity重建并不会调用该方法) class TimerViewModel : ViewModel() {private val timer: Timer Timer() //定时器类private var timeChangeListener: OnTimeChangeLister? nullprivate var currentSecond: Int 0fun start() {timer.schedule(timerTask {currentSecondtimeChangeListener?.onTimeChanged(currentSecond)}, 1000, 1000)}override fun onCleared() {super.onCleared()timer.cancel()}fun setOnTimeChangeListener(listener: OnTimeChangeLister) {timeChangeListener listener}interface OnTimeChangeLister {fun onTimeChanged(second: Int)} }ViewModel的实例化过程是通过ViewModelProvider来完成的。ViewModelProvider会判断ViewModel是否存在若存在则直接返回否则它会创建一个ViewModel。 class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val tv findViewByIdTextView(R.id.tv)val model ViewModelProvider(this).get(TimerViewModel::class.java)//获得ViewModel实例model.setOnTimeChangeListener(object : TimerViewModel.OnTimeChangeLister {override fun onTimeChanged(second: Int) {runOnUiThread {tv.text second.toString()}}})model.start()} }运行程序并旋转屏幕。当旋转屏幕导致Activity重建时计时器并没有停止。这意味着横/竖屏状态下的Activity所对应的ViewModel是同一个它并没有被销毁它所持有的数据也一直都存在着。 ViewModel的生命周期 ViewModel在获取ViewModel对象时会通过ViewModelProvider的传递来绑定对应的声明周期。ViewModel只有在Activity finish或者Fragment detach之后才会销毁。 在Fragments间分享数据 有时候一个Activity中的两个或多个Fragment需要分享数据或者相互通信这样就会带来很多问题比如数据获取相互确定生命周期。 使用ViewModel可以很好的解决这个问题。假设有这样两个Fragment一个Fragment提供一个列表另一个Fragment提供点击每个item现实的详细信息。 public class SharedViewModel extends ViewModel {private final MutableLiveDataItem selected new MutableLiveDataItem();public void select(Item item) {selected.setValue(item);}public LiveDataItem getSelected() {return selected;} }public class MasterFragment extends Fragment {private SharedViewModel model;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);model ViewModelProviders.of(getActivity()).get(SharedViewModel.class);//以上官方文档写法已被弃用采取以下写法ViewModel viewModel new ViewModelProvider(getActivity()/this).get(*ViewModel.class);itemSelector.setOnClickListener(item - {model.select(item);});} }public class DetailFragment extends LifecycleFragment {public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SharedViewModel model ViewModelProviders.of(getActivity()).get(SharedViewModel.class);//以上官方文档写法已被弃用采取以下写法ViewModel viewModel new ViewModelProvider(getActivity()/this).get(*ViewModel.class);ViewModel viewModel new ViewModelProvider(getActivity()/this).get(*ViewModel.class);model.getSelected().observe(this, { item -// update UI});} }两个Fragment都是通过getActivity()来获取ViewModelProvider。这意味着两个Activity都是获取的属于同一个Activity的同一个ShareViewModel实例。 这样做优点如下: Activity不需要写任何额外的代码也不需要关心Fragment之间的通信。Fragment不需要处理除SharedViewModel以外其他的代码。这两个Fragment不需要知道对方是否存在。Fragment的生命周期不会相互影响 ViewModel和SavedInstanceState对比 ViewModel使得在configuration change旋转屏幕等保存数据变的十分方便但是这不能用于应用被系统杀死时持久化数据。举个简单的例子有一个界面展示用户信息。 不应该把整个用户信息放到SavedInstanceState里而是把单个用户对应的id放到SavedInstanceState等到界面恢复时再通过id去获取详细的信息。这些详细的信息应该被存放在数据库中。 Jetpack ViewModel 并不等价于 MVVM ViewModel 这二者没有在同一个层次MVVM ViewModel是MVVM架构中的一个角色看不见摸不着只是一种思想。 而Jetpack ViewModel是一个实实在在的框架用于做状态托管有对应的作用域可跟随Activity/Fragment生命周期但这种特性恰好可以充当MVVM ViewModel的角色分隔数据层和视图层并做数据托管。 所以结论是Jetpack ViewModel可以充当MVVM ViewModel 但二者并不等价 但jetpack的组件是可以分别使用的所以可以先熟悉各个组件然后往自己的项目里套。 ViewModel原理 val model ViewModelProvider(this).get(TimerViewModel::class.java)首先看ViewModelProvider的源码: public class ViewModelProvider {private final Factory mFactory;private final ViewModelStore mViewModelStore;/*** Creates {code ViewModelProvider}. This will create {code ViewModels}* and retain them in a store of the given {code ViewModelStoreOwner}.* p* This method will use the* {link HasDefaultViewModelProviderFactory#getDefaultViewModelProviderFactory() default factory}* if the owner implements {link HasDefaultViewModelProviderFactory}. Otherwise, a* {link NewInstanceFactory} will be used.*/public ViewModelProvider(NonNull ViewModelStoreOwner owner) {this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory(): NewInstanceFactory.getInstance());}//比较常用的构造函数public ViewModelProvider(NonNull ViewModelStore store, NonNull Factory factory) {mFactory factory;mViewModelStore store;}public T extends ViewModel T get(NonNull ClassT 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);}//获得ViewModel实例public T extends ViewModel T get(NonNull String key, NonNull ClassT modelClass) {ViewModel viewModel mViewModelStore.get(key);if (modelClass.isInstance(viewModel)) {if (mFactory instanceof OnRequeryFactory) {((OnRequeryFactory) mFactory).onRequery(viewModel);}return (T) viewModel;} else {//noinspection StatementWithEmptyBodyif (viewModel ! null) {// TODO: log a warning.}}if (mFactory instanceof KeyedFactory) {viewModel ((KeyedFactory) mFactory).create(key, modelClass);} else {viewModel mFactory.create(modelClass);}mViewModelStore.put(key, viewModel);return (T) viewModel;}} ViewModelProvider接收一个ViewModelStoreOwner对象作为参数。在以上示例代码中该参数是this指代当前的Activity。这是因为我们的Activity继承自ComponentActivity而在androidx依赖包中ComponentActivity默认实现了ViewModelStoreOwner接口 public class ComponentActivity extends androidx.core.app.ComponentActivity implementsLifecycleOwner,ViewModelStoreOwner,SavedStateRegistryOwner,OnBackPressedDispatcherOwner {public ViewModelStore getViewModelStore() {if (getApplication() null) {throw new IllegalStateException(Your activity is not yet attached to the Application instance. You cant request ViewModel before onCreate call.);}if (mViewModelStore null) {NonConfigurationInstances nc (NonConfigurationInstances) getLastNonConfigurationInstance();if (nc ! null) {// Restore the ViewModelStore from NonConfigurationInstancesmViewModelStore nc.viewModelStore;}if (mViewModelStore null) {mViewModelStore new ViewModelStore();}}return mViewModelStore;} }public interface ViewModelStoreOwner {/*** Returns owned {link ViewModelStore}** return a {code ViewModelStore}*/NonNullViewModelStore getViewModelStore(); }ViewModelStore类的代码是: public class ViewModelStore {private final HashMapString, 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);}SetString keys() {return new HashSet(mMap.keySet());}/*** Clears internal storage and notifies ViewModels that they are no longer used.*/public final void clear() {for (ViewModel vm : mMap.values()) {vm.clear();}mMap.clear();} }从ViewModelStore的源码可以看出ViewModel实际上是以HashMapStringViewModel的形式被缓存起来了。ViewModel与页面之间没有直接的关联它们通过ViewModelProvider进行关联。 当页面需要ViewModel时会向ViewModelProvider索要ViewModelProvider检查该ViewModel是否已经存在于缓存中若存在则直接返回若不存在则实例化一个。 因此Activity由于配置变化导致的销毁重建并不会影响ViewModelViewModel是独立于页面而存在的。也正因为此我们在使用ViewModel时需要特别注意不要向ViewModel中传入任何类型的Context或带有Context引用的对象这可能会导致页面无法被销毁从而引发内存泄漏。 ViewModel与AndroidViewModel 在使用ViewModel时不能将任何类型的Context或含有Context引用的对象传入ViewModel因为这可能会导致内存泄漏。但如果你希望在ViewModel中使用Context该怎么办呢可以使用AndroidViewModel类它继承自ViewModel并接收Application作为Context。这意味着AndroidViewModel的生命周期和Application是一样的那么这就不算是一个内存泄漏了。 在上面的示例中我们通过自定义接口OnTimeChangeListener来完成ViewModel与页面之间的通信。这不是一个好的方案。Jetpack为我们提供了LiveData组件来解决这个问题。通过LiveData当ViewModel中的数据发生变化时页面能自动收到通知进而更新UI。
http://www.zqtcl.cn/news/223068/

相关文章:

  • 站内seo和站外seo区别wordpress演示数据
  • 建设旅游网站财务分析创意设计公司网站
  • 张家港网站优化wordpress调用图片上传
  • 做网站要商标吗房产网站 设计方案
  • 做网站的费用怎么做账客户案例 网站建设
  • 怎么查询网站的备案号城乡建设杂志网站
  • 婚恋网站哪家做的最好北斗导航2022最新版手机版
  • 别墅效果图网站重庆金融公司网站建设
  • 中兴能源建设有限公司网站企业营销策划及推广
  • 外贸英文网站制作WordPress对接微信公众号
  • 推广网站建设花费得多少钱哪些平台可以发布软文
  • wordpress网站检测购物app大全
  • 遵义建设厅官方网站 元丰兰州网站设计有限公司
  • 芜湖做网站的公司排名贵阳好的网站建设公司
  • 网站建设 骏域网站建设专家最有效的15个营销方法
  • 大连品牌官网建站为什么有些网站更新的信息看不到
  • 富阳市网站域名申请好了怎么做网站
  • 做药物分析必须知道的网站网站攻击一般有那些
  • 一般网站做哪些端口映射那个网站做境外自由行便宜
  • 网站的建站过程公司seo是什么意思
  • 胜利油田局域网主页入口seo自学网官网
  • 阜阳网站是网站开发与设计专业
  • 网站建设哪个品牌好网站新备案不能访问
  • 网站备案号申请流程华为企业文化
  • 服装网站目标互联网舆情报告
  • 1.网站开发的详细流程电商网站开发文档
  • 域名估价网站制作网站需要注意什么
  • 新浪云虚拟主机做电影网站用什么l软件做网站了
  • 方城网站建设猴痘的治疗方法
  • 做响应式网站有什么插件哔哩哔哩免费安装