MVVM框架的搭建(三)——网络请求

mvvm的网络框架的搭建

MVVM框架的搭建(一)——背景 MVVM框架的搭建(二)——项目搭建 MVVM框架的搭建(三)——网络请求

之前,我们简单的介绍了一下MVVM的框架的构成以及搭建的基本的demo 但是网络请求是我们日常开发当中,非常基本也是必须的一部分,下面 我们一起来梳理一下带有网络请求的MVVM。

首先我们先在项目里集成相关的依赖
/**
 * config.gradle用于配置项目中各种lib引用和版本号控制
 *
 * [module_*] 各module版本号及applicationId控制
 * 如需在各个module中升级更新版本号,请使用 module_[modulename]*的命名规则
 *
 * [project.ext.dependVersion] 中创建各个依赖库的版本号控制,需在类库名称后增加‘_version’
 *
 * [类库maven地址] 中创建各个类库的maven地址,同一类库需要引用多个类时,可以使用数组,要确保类库引用不重复
 *
 * [项目依赖列表] 中创建可以直接让module引用的依赖列表,以Deps结尾,原则上以类库功能分类,比如网络库,图片处理库
 * 尽量不要以类库本身的名字命名依赖列表
 *
 * 各个module中引用类库时尽量使用项目依赖列表中的项目,不要直接使用类库地址中的项目
 *
 * 需要添加新的类库时,先查询本列表和项目中是否已引用类似功能的类库,尽量不要添加重复功能的类库
 */
project.ext {
    compileSdkVersion = 27
    buildToolsVersion = '27.0.3'
    minSdkVersion = 16
    targetSdkVersion = 27

    //主app
    module_appApplicationId = 'yang.cehome.com.mvvmdemo'
    module_appVersionCode = 0001
    module_appVersionName = '1.0.0'
    module_appName = 'MVVM'

    //引用类库的版本号
    dependVersion = [
            kotlin_version     : '1.2.51',
            support_version    : '27.1.1',
            databinding_version: '3.2.0-alpha10',
            retrofit2_version  : '2.3.0',
            gson_version       : '2.8.5',
            rxandroid_version  : '2.1.0',
            rxjava_version     : '2.2.2'
    ]

    //*************************类库maven地址**************************
    kotlin_base = [kotlin_stdlib_jdk8: "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$dependVersion.kotlin_version"
    ]
    supportLibs = [
            design      : "com.android.support:design:$dependVersion.support_version",
            appcompat_v7: "com.android.support:appcompat-v7:$dependVersion.support_version",
            constraint  : 'com.android.support.constraint:constraint-layout:1.1.3']

    databindingLibs = [databinding: "com.android.databinding:compiler:$dependVersion.databinding_version"]

    network = [
            retrofit           : "com.squareup.retrofit2:retrofit:$dependVersion.retrofit2_version",
            retrofit_converters: "com.squareup.retrofit2:converter-gson:$dependVersion.retrofit2_version",
            retrofit_adapters  : "com.squareup.retrofit2:adapter-rxjava2:$dependVersion.retrofit2_version"]

    gson = [gson: "com.google.code.gson:gson:$dependVersion.gson_version"]

    rxandroid = [rxandroid: "io.reactivex.rxjava2:rxandroid:$dependVersion.rxandroid_version"]

    rxjava = [rxjava: "io.reactivex.rxjava2:rxjava:$dependVersion.rxjava_version"]

    //********************项目依赖列表**********************
    kotlinDeps = [kotlin_base.values()]
    supportDeps = [supportLibs.values()]
    databindingDeps = [databindingLibs.values()]
    networkDeps = [network.values(), gson.values()]
    rxDeps = [rxandroid.values(), rxjava.values()]
}

依赖的方式我们依旧采取这种统一管理的方式。 然后 我们在工程依赖

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project.ext.kotlinDeps
    implementation project.ext.supportDeps
    implementation project.ext.networkDeps
    implementation project.ext.rxDeps
    annotationProcessor  project.ext.databindingDeps
}
代码实现

我们增加了一个remote的包 同时 增加了一个Service类 包的结构如图

这个接口我们就从网上找了一个关于手机号的省份的api (想和Gsonfromat一样把Json快速生成Kotlin的代码,推荐一个插件JsonToKotlinClass)这样就可以快速根据Json生成Kotlin的类,使用比较简单和GsonFromat一样的。 如图

迅速生成了对应的实体。

data class WeatherInfoData(
    val weatherinfo: Weatherinfo
)

data class Weatherinfo(
    val AP: String,
    val Radar: String,
    val SD: String,
    val WD: String,
    val WS: String,
    val WSE: String,
    val city: String,
    val cityid: String,
    val isRadar: String,
    val njd: String,
    val sm: String,
    val temp: String,
    val time: String
)

现在开始写请求

package yang.cehome.com.mvvmdemo.model.remote
import io.reactivex.Single
import retrofit2.http.GET
import yang.cehome.com.mvvmdemo.model.data.WeatherInfoData

/**
 * @author yangzc
 *  @data 2018/9/11 18:13
 *  @desc WeatherService
 *
 */
interface WeatherService {
    //获取天气
    @GET("/data/sk/101190408.html")
    fun getWeatherInfo(): Single<WeatherInfoData>

}

下面我们开始写ViewModel

package yang.cehome.com.mvvmdemo.viewmodel

import android.databinding.ObservableField
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import yang.cehome.com.mvvmdemo.model.data.WeatherInfoData
import yang.cehome.com.mvvmdemo.model.remote.WeatherService

/**
 * @author yangzc
 *  @data 2018/9/12 14:20
 *  @desc WeatherViewModel
 *
 */
class WeatherViewModel(val remote: WeatherService) {
    /******data******/
    val weatherinfo = ObservableField<String>()

    /******binding******/
    fun loadWeather() {
        remote.getWeatherInfo()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ t: WeatherInfoData? ->
                    weatherinfo.set(t?.let { it.weatherinfo.toString() })
                }, { t: Throwable? ->
                    weatherinfo.set(t?.message ?: "error")
                })
    }
}

接下来 我们一起看一下Activity当中的代码

package yang.cehome.com.mvvmdemo.view

import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import yang.cehome.com.mvvmdemo.R
import yang.cehome.com.mvvmdemo.databinding.ActivityMainBinding
import yang.cehome.com.mvvmdemo.model.data.Onclick
import yang.cehome.com.mvvmdemo.model.remote.WeatherService
import yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel
import yang.cehome.com.mvvmdemo.viewmodel.WeatherViewModel
/**
 * MVVM 当中的一个V层 将三者联系起来
 */
class MainActivity : AppCompatActivity() {
    private lateinit var mBinding: ActivityMainBinding
    private lateinit var mViewMode: OnclikViewModel
    private lateinit var mViewMode2: WeatherViewModel


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        /////model
        val onclick = Onclick("me", 0)
        ///ViewModel
        mViewMode = OnclikViewModel(onclick)
        ///binding


        val remote = Retrofit.Builder()
                .baseUrl("http://www.weather.com.cn")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build().create(WeatherService::class.java)

        mViewMode2 = WeatherViewModel(remote)
        mBinding.vm = mViewMode
        mBinding.remote = mViewMode2
    }
}

我们可以看到 在Activity当中承担了请求网络的角色 但是 对于数据的处理并没有在这里体现,同时 我们可以看到对于点击的操作以及显示并没有出现在这里。 接下来我再看一下布局文件,大家可以看到新的结构对于布局文件的重要性

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <!--需要的viewModel,通过mBinding.vm=mViewMode注入-->
        <variable
        name="vm"
        type="yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel" />

        <variable
            name="remote"
            type="yang.cehome.com.mvvmdemo.viewmodel.WeatherViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".view.MainActivity">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp">

            <Button
                android:id="@+id/bt_onclick"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->vm.click()}"
                android:text="来点一下试试" />

            <TextView
                android:id="@+id/tv_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/bt_onclick"
                android:layout_marginBottom="20dp"
                android:text="@{vm.info}"
                android:textSize="16sp"
                tools:text="点了0次" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="60dp">


            <Button
                android:id="@+id/bt_load"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->remote.loadWeather()}"
                android:text="网络获取" />

            <TextView
                android:id="@+id/tv_load"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/bt_load"
                android:layout_marginBottom="50dp"
                android:text="@{remote.weatherinfo}"
                android:textSize="16sp"
                />

        </RelativeLayout>
    </LinearLayout>
</layout>

当然在最后别忘了加上网络权限

   <uses-permission android:name="android.permission.INTERNET" />

接下来我们就可以看到效果了

网络.gif

至此完成了MVVM框架的搭建,也完成了基本的网络请求,对于MVVM框架有了一个更加深刻的了解,那么接下来要进一步优化一下框架,丰富的功能。

项目地址

https://github.com/yang0range/MVVM

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏林冠宏的技术文章

GreenDao 兼容升级,保留旧数据的---全方面解决方案

作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:htt...

33050
来自专栏Android干货园

Retrofit--使用Retrofit时怎样去设置OKHttp

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/51...

10320
来自专栏月牙寂

k8s源码分析-----kubectl(3)主要框架

第一时间获取文章,可以关注本人公众号 月牙寂道长 yueyajidaozhang

72840
来自专栏非著名程序员

Android:全面解析熟悉而陌生 的 Application 类使用

前言 Applicaiton类在 Android开发中非常常见,可是你真的了解Applicaiton类吗? 本文将全面解析Applicaiton类,包括特点、方...

26350
来自专栏Android-JessYan

看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?

原文地址: http://www.jianshu.com/p/4bbecd0bb027

1.1K30
来自专栏yang0range

Android面试

要想知道如何使用多进程,先要知道Android里的多进程概念。一般情况下,一个应用程序就是一个进程,这个进程名称就是应用程序包名。我们知道进程是系统分配资源和调...

28840
来自专栏木宛城主

Unity应用架构设计(2)——使用中介者模式解耦ViewModel之间通信

当你开发一个客户端应用程序的时候,往往一个单页会包含很多子模块,在不同的平台下,这些子模块又被叫成子View(视图),或者子Component(组件)。越是复...

300100
来自专栏向治洪

Android 使用android-support-multidex解决Dex超出方法数的限制问题

随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的...

38080
来自专栏为数不多的Android技巧

Android插件化原理解析——广播的管理

在Activity生命周期管理 以及 插件加载机制 中我们详细讲述了插件化过程中对于Activity组件的处理方式,为了实现Activity的插件化我们付出了相...

11920
来自专栏MelonTeam专栏

一种下载管理方案的设计与实现

导语: 4G时代流量资费大幅下降,各种“WBQ”卡惊艳出世——在此背景下,下载对于移动端已不再是一种昂贵的高成本行为。同时EMMC、UFS等存储介质的发展也...

347110

扫码关注云+社区

领取腾讯云代金券