本文主要是介绍你该拥有自己的一套项目结构----Kotlin+Dagger2+MVP+Rx+Retrofit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言:
架构是什么?框架是什么?
其实很简单,一句话:框架是软件,架构不是软件。框架落脚在“架”字上,可以理解成名词性的,是一个客观性的名词存在,如.Net Framework;而架构体现在“构”字上,理解成构造,是一个动词性的,是一系列动作发生的策略性体现。先大局后局部,就出现了架构;先通用后专用,就出现了框架。
让我这个菜鸟LOL玩家看来:架构就是LOL里面的一套打法、战术,框架则是精确到QWER+走位。
1.以前不懂得架构思想的我,拿到一个项目之后,囫囵吞枣的按照需求文档,也能“有模有样”的按时提交成果。这样直接导致的后果就是,很怕leader又要改改改,加加加。
2.当然网上有很多优秀的架构,别人的东西不是百分百适合自己的项目,所以要结合理解,搭建出属于自己熟悉的一套架构。随着经验的增长,从而不断的完善自己的那一套。
3.本文难点不大,高手勿喷,欢迎指点。希望起到抛砖迎玉的作用,让每个开发者都有自己熟悉的一套架构。
源码:https://github.com/KomoriWu/Http.git
目录
一、MVP 设计模式
二、网络请求框架(Rx+Retrofit )
三、Kotlin
四、Dagger2
此文不在讲述一、二 请看 上一篇博文
http://blog.csdn.net/sinat_27033869/article/details/66972339
二、网络请求框架(Rx+Retrofit )
其中相比上一次,我把网络请求的框架完全提取出来,直接无脑使用就行。
Android studio 导入方法:
第一步:
allprojects {repositories {...maven { url 'https://jitpack.io' }}}
第二步:
dependencies {compile 'com.github.KomoriWu:Http:v1.0.0'}
在项目中的调用
//这里框架我之前是用Java语言写的,demo中的调用我用的Kotlin。之后我会响应号召,把网络请求的框架也改为Kotlin
1.
调用者只需编写两个简单的类即可。
public class ArticleApi extends BaseApi {private String mPage;private String mSize;public ArticleApi(RxAppCompatActivity rxAppCompatActivity, String page, String size,HttpOnNextListener listener) {super(rxAppCompatActivity, listener,BASE_URL);this.mPage = page;this.mSize = size;//是否显示加载框setShowProgress(false);}//提供请求所需字段的数据@Overridepublic Observable getObservable(Retrofit retrofit) {Map<String, String> map = new HashMap<>();map.put("page", mPage);map.put("size", mSize);HttpService service = retrofit.create(HttpService.class);return service.getAllArticles(map);//传数据到HttpService}
}
public interface HttpService {@GET(GET_ALL_ARTICLES)Observable<ArticleBody> getAllArticles(@QueryMap Map<String, String> map);
}
在程序中调用:
val articleApi: ArticleApi = ArticleApi(context as RxAppCompatActivity, page, size, object :HttpOnNextListener<ArticleBody>() {override fun onNext(t: ArticleBody?) {onLoadListListener.onSuccess(t);}override fun onError(e: Throwable?) {onLoadListListener.onFail(e);}})HttpManager.getInstance().doHttpDeal(articleApi)
十分清爽,无脑使用。实现原理可以看我上一篇博客,这里只是交大家如何使用。结合demo看,效果更佳。
三、kotlin
Demo中的代码大家可以发现,既有Java 也有 Kotlin。的确100%融合,有些地方用Kotlin省心很多。
kotlin是什么?多的话我不说,早学晚学都要学。以后找Android,不会这个,估计就被挤下去了。
刚开始接触kotlin时,十分惧怕,看网上博客一脸懵逼。很难吗?其实不然,大家只要搞懂几个关键点,之后写代码,多使用官方API文档。上手还是很快的。
1.配置
第一种:as在3.0以下的需要安装插件:
Android Studio的Kotlin插件, 用于支持Kotlin的语言特性.
选择: Preferences -> Plugins -> Install JetBrains plugin -> kotlin.
第二种:也是我极力推荐的,将as升级到3.0,一切省心省事,3.0的版本优化很大,完全支持kotlin。
2.添加依赖
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"compile 'org.jetbrains.anko:anko-sdk15:0.8.3'
//快捷键:选择Code -> Convert Java File to Kotlin File, 更好的学习kotlin
Kotlin API 入门
1. 变量
⼀次赋值(只读)的局部变量:
val a: Int = 1 // ⽴即赋值
val b = 2 // ⾃动推断出 `Int` 类型
val c: Int // 如果没有初始值类型不能省略
c = 3 // 明确赋值
可变变量:
var x = 5 // ⾃动推断出 `Int` 类型
x += 1
当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引⽤可为空。
如果 str 的内容不是数字返回 null
2.条件
在 Kotlin 中,if是⼀个表达式,即它会返回⼀个值。 因此就不需要三元运算符(条件 ? 然后 : 否则),因为普通的 if 就能胜任这个⻆⾊
// 传统⽤法
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b
if的分⽀可以是代码块,最后的表达式作为该块的值:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
如果你使⽤ if 作为表达式⽽不是语句(例如:返回它的值或者 把它赋给变量),该表达式需要有 else 分⽀。
3.循环
when 取代了类 C 语⾔的 switch 操作符。其最简单的形式如下:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
如果很多分⽀需要⽤相同的⽅式处理,则可以把多个分⽀条件放在⼀起,⽤逗号分隔:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
我们可以⽤任意表达式(⽽不只是常量)作为分⽀条件
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
我们也可以检测⼀个值在(in)或者不在(!in)⼀个区间或者集合中:
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
For 循环
for 循环可以对任何提供迭代器(iterator)的对象进⾏遍历,语法如下:
for (item in collection) print(item)
如果你想要通过索引遍历⼀个数组或者⼀个 list,你可以这么做
for (i in array.indices) {
print(array[i])
}
4.函数
定义函数:带有两个 Int 参数、返回 Int 的函数:
fun+方法名+参数(参数名:类型)+返回类型(可以不写,自动判断。返回为空可省略)
fun sum(a: Int, b: Int): Int {
return a + b
}
将表达式作为函数体、返回值类型⾃动推断的函数:
fun sum(a: Int, b: Int) = a + b
函数返回⽆意义的值:
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
Unit 返回类型可以省略
//以上为Kotlin一些基础语法,简单易上手,有了这些看懂demo无压力
四、Dagger2在MVP中的使用
Dagger2:Dagger2现在由Google接手维护。是一个依赖注入的框架。
依赖注入:是面向对象编程的一种设计模式,其目的是为了降低程序耦合,这个耦合就是类之间的依赖引起的。
网上关于Dagger2的文章太多,比较后推荐这篇:
http://www.open-open.com/lib/view/open1482201981550.html
具体项目中我们如何使用呢?
先来看Demo的MVP+Dagger2的项目结构:
可能你觉得分包太多,但是实际层次更分明,结构更简单。日后维护、迭代再也不怕了。
MVP中的model :网络数据请求
class ArticleModelImpl : ArticleModel {override fun loaderArticle(context: Context, page: String, size: String,onLoadListListener: OnLoadListListener) {val articleApi: ArticleApi = ArticleApi(context as RxAppCompatActivity, page, size, object :HttpOnNextListener<ArticleBody>() {override fun onNext(t: ArticleBody?) {onLoadListListener.onSuccess(t);}override fun onError(e: Throwable?) {onLoadListListener.onFail(e);}})//采用已经封装完毕的RX+Retrofit框架HttpManager.getInstance().doHttpDeal(articleApi)}interface OnLoadListListener {fun onSuccess(t: ArticleBody?)fun onFail(e: Throwable?)}
}
MVP中的View :将Model中得到的数据传给activity显示出来
interface ArticleView {fun addArticleList(articleBody: ArticleBody?)
}
MVP中的Presenter :中间体。将model与view连接起来
class ArticlePresenterImpl(private var mContext: Context,private var mArticleView: ArticleView) :ArticlePresenter, ArticleModelImpl.OnLoadListListener {private var mArticleModel: ArticleModel? = nullinit {mArticleModel = ArticleModelImpl()}override fun loaderArticle(page: String, size: String) {mArticleModel?.loaderArticle(mContext, page, size, this)}override fun onSuccess(t: ArticleBody?) {mArticleView.addArticleList(t)}override fun onFail(e: Throwable?) {}}
activity中的调用:
常规调用为:
lateinit var mArticlePresenter: ArticlePresenter
mArticlePresenter = ArticlePresenterImpl(this, this) mArticlePresenter?.loaderArticle("1", "8")
结合Dagger2
1.Module :生成依赖对象。@Module就是用来标准这个类的,而@Provide则是用来标注具体提供依赖对象的方法。由@Module 与@Provides 完成。提供数据。
我们这里提供数据的类是ArticlePresenterImpl
@Module
class ArticleModule(private var mContext: Context,private var mArticleView: ArticleView) {@Providesfun providePresenter(): ArticlePresenter {return ArticlePresenterImpl(mContext, mArticleView)}
}
2.Component:是依赖需求方和依赖提供方之间的桥梁。
Dagger2提供依赖的是ArticleModule这个类。
Dagger2得到依赖的是MainActivity
@Component(modules = arrayOf(ArticleModule::class))
interface ArticleComponent {fun inject(mainActivity: MainActivity)
}
3.依赖需求方:在activity中的调用。
完成这些之后我们需要Build下项目,让Dagger2帮我们生成相关的Java类。接着我们就可以在activity中调用Dagger2生成的DaggerArticleComponent来实现注入
@Injectlateinit var mArticlePresenter: ArticlePresenter
DaggerArticleComponent.builder().articleModule(ArticleModule(this, this)).build().inject(this)mArticlePresenter.loaderArticle("1", "8")
下载demo学习更佳,欢迎start:
https://github.com/KomoriWu/Http.git
这篇关于你该拥有自己的一套项目结构----Kotlin+Dagger2+MVP+Rx+Retrofit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!