继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Android 项目架构,你真的了解吗?

青春有我
关注TA
已关注
手记 1072
粉丝 205
获赞 1007

前言

为了帮助开发着打造一款优秀的APP,Google可谓费尽心力,推出了各种诸如MVP,MVVM等等项目架构的思路,帮助开发者更加高效的开发,尽管这样,Google还是接着推出了一个新的项目架构,以便给予开发者更多的选择,至于这种架构思路和MVP等框架的优劣,各位看完文章或许自有定论。

1.生命周期

在移动操作系统上开发软件其实是十分复杂的一件事情,因为我们随时需要面对系统和用户的各种不可预料的操作,很多时候,事情并不向着我们预设的方向方向进展。因此系统向我们提供了核心组件的生命周期这种东西,告知我们的APP正处在什么样的状况中,以便于我们做出相应的处理。

webp

如上图。虽然Google给出了Activity非常详尽的生命周期结构,因此我们对根据生命周期做出相应的合理的安排,比如添加和移除实时GPS位置监听:

webp

可是随着业务的逐渐复杂,我们可能在添加监听之间需要向服务器验证某些用户信息,等返回信息正确才去监听定位。那么在网络异步回调的时候,我们就很难知道当前的activity的生命周期状态。

webp

如果发生上图的情况,那么我们的占用的相关资源就可能永远无法移除了。这还只是冰山一角,大家尽可以想想,当我们的异步调用面对无法预知的用户操作和系统处理的时候,什么问题都可能发生。

总而言之,由于我们对于UI实时的状态做不到了如指掌,以至于对数据和逻辑的处理就无法尽善尽美。这是类似隐患得不到很好的解决根本原因。

2. Google大礼包

这次Google推出了一套新的项目架构组件和架构思路,从UI到Data,帮助我们更加精准的开发自己的APP。

2.1 核心:Lifecycle Components

这套架构最核心的就是生命周期组件,:Lifecycle Components用于管理UI控制器(Activity/Freagment)的生命周期,方便查询当前组件生命周期的状态。

可查询的状态如下:

webp

具体的使用方式有两种:

继承LifecycleActivity/LifecycleFragment即可

自己实现LifecycleRegistryOwner接口

java

// 通过继承,就已经将自己的生命周期的交给了Lifecycle Components管理了。

publicclassMainActivityextendsLifecycleActivity{

}

那我们如何使用呢?

// 通过继承LifecycleObserver,保证我们可以通过注解或者接口查询UI的生命周期

publicclassMyTestimplementsLifecycleObserver{

privateLifecycle lifecycle;

// Lifecycle包含了当前组件的生命周期

publicMyTest(Lifecycle lifecycle){

lifecycle.addObserver(this);

this.lifecycle=lifecycle;

    }

// 当onResume发生的时候,该方法被调用

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)

publicvoidresume(){

Log.i("TAG","it called when resume ");

    }

publicvoiddoTest(String s){

// 随时可以查询当前的UI状态

if(lifecycle.getCurrentState().equals(Lifecycle.State.RESUMED)){

Log.i("TAG","resume");

}else{

Log.i("TAG","is not resume !! ");

        }

    }

}

publicclassMainActivityextendsLifecycleActivity{

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

//将当前Activity的生命周期传递到MyTest中即可

MyTest myTest=newMyTest(this.getLifecycle());

    }

}

看到这里,你一定心头一喜,如果有这个组件,那么我们就完全有能力将Activity作为一个UI的控制器,仅仅用来显示UI和相应用户操作,把Activity的大小缩小至最小。不用着急,大礼包远不止这些。

3.ViewModel和LiveData

ViewModel 是一个UI相关数据的暂存器,当所有相关的UI都finish掉的时候,它才会清除自己的数据。

LiveData则是一个持有具体数据并且可被观察,能感知生命周期的组件(它就像RxJava中一个能遵循组件生命周期的Observable)

他俩的关系,就是,ViewModel负责管理着不同的LiveData,并把它提供给UI。

3.1 LiveData

我们可以先来说说LiveData。由于它已经能够感知生命周期,也就意味着我们并不需要在去查询当前UI的生命周期,由于可被观察,也就意味着当它持有的数据发生改变,观察者可以立即受到信息。livedata最重要的方法是一下几个:

onActive()// 当前LiveData有超过一个的活跃的观察者时,被调用

onInactive()// 当前没有任何活跃的观察时,着被调用

setValue()// 勇于改变当前数据,这样观察者可以受到改变后的数据。

// 观察数据变化,并感知当前UI的生命周期

observe(LifecycleOwner owner, Observer observer)

这里有一个活跃的观察者的概念,我们不妨把它放在后面来看。LiveData的用法如下:

publicclassLocationLiveDataextendsLiveData{

privateLocationManager locationManager;

privateSimpleLocationListener listener =newSimpleLocationListener() {

@Override

publicvoidonLocationChanged(Location location){

            setValue(location);

        }

    };

publicLocationLiveData(Context context){

        locationManager = (LocationManager) context.getSystemService(

                Context.LOCATION_SERVICE);

    }

@Override

protectedvoidonActive(){

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, listener);

    }

@Override

protectedvoidonInactive(){

        locationManager.removeUpdates(listener);

    }

}

publicclassMainActivityextendsLifecycleActivity{

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

LiveData myLocationListener =newLocationLiveData();

/*

        * observe(LifecycleOwner owner, Observer observer)

        * 这个方法就是向LiveData中添加观察者,

        * LiveData则可以通过LifecycleOwner来判断

        * 当前传入的观察者是否是活跃的(也就是UI是否可见了)

        */

myLocationListener.observe(this,newObserver() {

@Override

publicvoidonChanged(@Nullable Location location){

// update

//当LiveData中通过setValue()修改了数据时,

//这里将会受到修改后的数据

            }

        });

    }

}

好了,LiveData基本的用法讲完了,由于有了LiveData,我们的data更加“智能”了。当UI不可见的时候,改变的数据将不会被更新到UI上。

而且如果数据在不同的UI界面都会被用到的时候,我们还可以一个单例的LiveData,为不同的UI提供统一的数据。这些操作就不去细讲了。

现在回头看LiveData,我们发现它至少有以下几个优点:

可以避免内存泄露:由于 Observer 和 Lifecycle 绑定,当 Lifecycle 被销毁后,Observer 自动被清理。

避免在 Activity 被销毁后更新数据导致的崩溃情况

数据可共享

数据更新更智能:当数据在UI不可见的时候更新了,在恢复可见的时候,最新的数据会及时更新到UI上。

不需要在Activity中额外处理生命周期事件

一颗赛艇!

3.2 ViewModel

ViewModel则相对简单些,因为他的作用是暂存UI相关的数据,保证即使Activity配置更改,重新创建时,数据依然能够被保存好。

基本用法如下:

publicclassMyViewModelextendsViewModel{

// MyViewModel用于管理不同的LiveData

privateMutableLiveData> users;

publicLiveData> getUsers() {

if(users ==null) {

users =newMutableLiveData>();

            loadUsers();

        }

returnusers;

    }

privatevoidloadUsers(){

// do async operation to fetch users

    }

}

publicclassMyActivityextendsAppCompatActivity{

publicvoidonCreate(Bundle savedInstanceState){

// 通过了ViewModelProviders来获取ViewModel

// 用户获取和Activity绑定的ViewModel

MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);

model.getUsers().observe(this, users -> {

// update UI

        });

    }

}



作者:Android架构
链接:https://www.jianshu.com/p/45ef2ed92d44


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP