android编程框架是什么意思,Android开发-浅谈架构(一)

写在前面的话

嗯 聊聊架构。 这段时间一直在维护旧项目。 包括自己之前写的新项目 越来越发现 一个架构清晰的项目往往让人赏心悦目。不至于在一个bug丢过来之后手足无措。包括以后别人接收自己的项目 能很快上手 何乐而不为呢?

曾经的"MVC"

先从我们曾经的 "MVC" 说起, "MVC" 全名 "Model View Controller".即 视图层(View), 控制层(Controller),模型层(Model).他们之间的关系 如图:

8418756eb708

MVC

视图层(View) 一般由 xml布局文件担任 控制层(Controller) 一般由 activity和fragment 担任 模型层 (Model) 一般指的是 抽离出来的接口扩展。 尝尝可以复用的那一部分。 你只需要把接口 在Controller 抛出。 更新 View即可。其实我们刚开始参与项目开发 技术薄弱的时候 都会想到把复用的部分抽离出来 但是activity类写的很臃肿 至少不够优雅这其实就是MVC

写到这里 我们知道android中 Controller 控制层一般有Activity(主要)和fragment 担任。但是activity类中 常常包含一些ui 初始化 或者 网络 第三方sdk 的初始化又或者是业务逻辑。那么 这样写起代码层就会变得臃肿。而且不够优雅。那么MVP就从MVC中眼花诞生了。

8418756eb708

MVP

8418756eb708

MVP中的model层继续沿用MVC中的model

大家看这个图 也许不是很清楚或者说不是太理解。

在这里 "View" 由presenter中的接口担任 实现向View实现类通信,你也可以在Android组件中实现它。有时最好直接使用Activity,Fragment或自定义View。>The view that receives commands from a presenter in MVP, is referred to as "view"

先说Model: 它是一个负责管理数据的接口。模型的职责包括使用API、缓存数据、管理数据库等。该模型也可以是一个接口,与其他模块负责这些职责的沟通。例如,如果您使用的是存储库模式,则该模型可能是一个存储库。如果您使用的是干净的建筑,相反,该模型可以关联。(翻译过来略显生硬 简而言之 Model层是数据访问层,如数据库API或远程服务器API)

Presenter:大家可以看到Model和View是完全没有交互的。那么 Presenter则担当Model与View之间的中间人。你所有的业务逻辑都属于它。Presenter负责查询模型和更新视图,响应用户交互更新模型。

View:The view can be implemented by Activities, Fragments, any Android widget or anything that can do operations like showing a ProgressBar, updating a TextView, populating a RecyclerView and so on.(这个翻译起来有点尴尬 感觉大家应该都能看懂)

8418756eb708

对照MVC图来看 我们发现 View 中出现了 而Presenter中也出现了 .什么意思呢? 我们看Presenter中的代码实例:

8418756eb708

View中的TicTacToeView示例

关于

怎么写Model

如何理解View

如何写Presenter

参考 MVP详解

关于MVP文字性的描述就这么多。其实网上大部分讲解都是套三者之间的关系交互图来讲的。只有理解了尝试敲几遍就差不多会了。另外 符合项目需要的才是最好的。下面我尝试着动手仿照 ONE 一个app将MVP模式套入其中练手(项目会不断完善的 架构 分包开始)

先截个图 看一下目前大致的结构。

8418756eb708

aaa.png

没用到Presenter之前切换Fragment MainActivity切换标签页:

FragmentUtils fragmentUtil = new FragmentUtils(this, R.id.view_container);

fragmentUtil.switchTo(OneFragment.class);

mBinding.radio.setOnCheckedChangeListener((group, checkedId) -> {

switch (checkedId) {

case R.id.home_one:

fragmentUtil.switchTo(OneFragment.class);

break;

case R.id.home_reading:

fragmentUtil.switchTo(ReadingFragment.class);

break;

case R.id.home_music:

fragmentUtil.switchTo(MusicFragment.class);

break;

case R.id.home_movie:

fragmentUtil.switchTo(MovieFragment.class);

break;

default:

break;

}

});

用到Presenter之后:

if(presenter==null)

presenter = new MainTabPresenter(this, mBinding.radio);

presenter.switchTo();

其中 HomeActivity 类:

public class HomeActivity extends BaseActivity {

private MainTabPresenter presenter;

@Override

protected int getLayoutId() {

return R.layout.home_act;

}

@Override

protected void setupView() {

if(presenter==null)

presenter = new MainTabPresenter(this, mBinding.radio);

presenter.switchTo();

}

}

BaseActivity类:

public abstract class BaseActivity extends AppCompatActivity{

protected T mBinding;

protected ApiInteractor api;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initLayout();

}

private void initLayout() {

AppComponent appComponent = ((App) getApplication()).getAppComponent();

api = appComponent.getApiInteractor();

ViewDataBinding inflate = DataBindingUtil.setContentView(this, getLayoutId());

mBinding = DataBindingUtil.bind(inflate.getRoot());

if (mBinding == null) {

if (getLayoutId() == 0) {

throw new InflateException("activity no source_ID");

} else {

throw new NullPointerException("mBinding==NULL");

}

}

setupView();

}

@LayoutRes

protected abstract int getLayoutId();

protected abstract void setupView();

}

Presenter类:

public class MainTabPresenter implements MainTabContract.Presenter {

private RadioGroup radioGroup;

private final FragmentActivity mContext;

public MainTabPresenter(@Nullable FragmentActivity mActivity, @Nullable RadioGroup group){

mContext = checkNotNull(mActivity, "FragmentActivity cannot be null!");

radioGroup = checkNotNull(group, "RadioGroup cannot be null!");

}

@Override

public void switchTo() {

FragmentUtils fragmentUtil = new FragmentUtils(mContext, R.id.view_container);

fragmentUtil.switchTo(OneFragment.class);

radioGroup.setOnCheckedChangeListener((group1, checkedId) -> {

switch (checkedId) {

case R.id.home_one:

fragmentUtil.switchTo(OneFragment.class);

break;

case R.id.home_reading:

fragmentUtil.switchTo(ReadingFragment.class);

break;

case R.id.home_music:

fragmentUtil.switchTo(MusicFragment.class);

break;

case R.id.home_movie:

fragmentUtil.switchTo(MovieFragment.class);

break;

default:

break;

}

});

}

@Override

public void start() {//有些地方 RxJava MediaPlayer Handler 等生命周期用得上

}

}

简单的逻辑代码交由Presenter 和Model协作实现。可能表述 和理解的不是太好 欢迎指正。Demo架构Dagger2+RxJava+Retrofit 雏形已经大致出现 后面会陆续补充一些使用的小技巧 和 第三方的插入 譬如 微信热修复 等等吧。谢谢大家~

等等 分享几个免费的api(侵删 谢谢)

干货Api

和风天气

one 抓包接口

欢迎加群:

QQ 群 521039620

原文博客地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值