Android-MVVM开发模式应用

Android-MVVM开发模式应用

CSDN:https://blog.csdn.net/chenzhen200638/article/details/82185190

MVVM开发模式,是多种先进的开发思想集成在一起形成的一种高效率开发解决方案。
其中涉及到哪些开发思想呢?
- MVC : 是一种把数据和视图分离解耦的思想,视图的展示由控制器进行分发跳转;
- DI : 依赖注入是指将组件的依赖通过外部以参数或其他形式注入。比如Dagger,就是依赖注入框架;
- IOC : 控制反转,控制反转是将组件间的依赖关系从程序内部提到外部来管理;


开始搭建mvvm开发框架,前提需要了解Dagger的使用。

一、引入第三方库

在Android的工程目录Gradle中加入以下库


project.ext {
    retrofitVersion = "2.3.0"
    okhttpVersion = "3.9.0"
    supportVersion = "27.0.2"
    web3jVersion = "3.0.1-android"
    gethVersion = "1.7.0"
    gsonVersion = "2.8.2"
    rxJavaVersion = "2.1.6"
    rxAndroidVersion = "2.0.1"
    daggerVersion = "2.11"
}

dependencies {
    // Http client --网络库
    implementation "com.squareup.retrofit2:retrofit:$project.retrofitVersion"
    implementation "com.squareup.retrofit2:converter-gson:$project.retrofitVersion"
    implementation "com.squareup.retrofit2:adapter-rxjava2:$project.retrofitVersion"
    implementation "com.squareup.okhttp3:okhttp:$project.okhttpVersion"
    implementation "com.google.code.gson:gson:$project.gsonVersion"

    // RxJava 内存优化
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.1.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.1.1'

    // RxJava2.x
    implementation "io.reactivex.rxjava2:rxjava:$project.rxJavaVersion"
    implementation "io.reactivex.rxjava2:rxandroid:$project.rxAndroidVersion"

    // Lifecycle 生命周期
    implementation "android.arch.lifecycle:runtime:1.0.3"
    implementation "android.arch.lifecycle:extensions:1.0.0"

    // Dagger 2 DI依赖注入库
    // Dagger core
    implementation "com.google.dagger:dagger:$project.daggerVersion"
    annotationProcessor "com.google.dagger:dagger-compiler:$project.daggerVersion"
    // Dagger Android
    implementation "com.google.dagger:dagger-android-support:$project.daggerVersion"
    annotationProcessor "com.google.dagger:dagger-android-processor:$project.daggerVersion"
    // if you are not using support library, include this instead
    implementation "com.google.dagger:dagger-android:$project.daggerVersion"
}

现在我们来编写具体的业务代码,包的划分为 di,entity,service,viewmodle,ui几个目录
- di: 依赖注入相关的代码
- entity: 实体类
- service: 网络请求,数据库相关代码
- viewmodle: 业务逻辑代码
- ui : activity界面视图相关代码

二、编写Service数据源API

//数据库操作代码,结合了RxJava2.x返回的都是Observeble对象;
public class RealmService {

    public Single<List<Student>> findAllStudent() {
        return Single.fromCallable(() -> {
            final List<Student> students = new ArrayList<>();
            Realm realm = Realm.getDefaultInstance();
            try {
                realm.executeTransaction(r -> {
                    RealmResults<Student> rs = realm.where(Student.class).findAll();
                    students.addAll(realm.copyFromRealm(rs));
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (realm != null) {
                    realm.close();
                }
            }
            return students;
        });
    }

    public Completable addStudent(Student student) {
        return Completable.fromAction(() -> {
            Realm realm = Realm.getDefaultInstance();
            try {
                realm.executeTransaction(r -> {
                    Student s = realm.createObject(Student.class,
                    UUID.randomUUID().toString());
                    s.setName(student.getName());
                    s.setAddress(student.getAddress());
                    s.setAge(student.getAge());
                    realm.copyFromRealm(s);
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (realm != null) {
                    realm.close();
                }
            }
        });

}

定义实体类学生

public class Student extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;
    private String address;
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }
}

三、编写ViewModle业务逻辑

3.1 工厂类
public class RealmServiceModelFactory implements ViewModelProvider.Factory  {

    private final RealmService mRealmService;
    @Inject
    public RealmServiceModelFactory(RealmService mRealmService) {
        this.mRealmService = mRealmService;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        return (T)new RealmServiceModel(mRealmService);
    }
}

3.2 业务逻辑的基类

基类主要封装好通用的异常,进度条显隐控制逻辑;

public class BaseViewModel extends ViewModel {
    protected final MutableLiveData<String> error = new MutableLiveData<>();
    protected final MutableLiveData<Boolean> progress = new MutableLiveData<>();
    protected Disposable disposable;
    @Override
    protected void onCleared() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }

    public LiveData<String> error() {
        return error;
    }

    public LiveData<Boolean> progress() {
        return progress;
    }

    protected void onError(Throwable throwable) {
        error.postValue(throwable.getMessage());
    }
}

3.3 业务逻辑Modle
package realm.com.xn.realmdatabase.viewmodel;

import android.arch.lifecycle.MutableLiveData;

import java.util.List;
import java.util.concurrent.TimeUnit;

import realm.com.xn.realmdatabase.entity.Student;
import realm.com.xn.realmdatabase.service.RealmService;

/**
 * Created by xn068074 on 2018/8/24.
 */

public class RealmServiceModel extends BaseViewModel {

    private final RealmService mRealmService;
    private final MutableLiveData<List<Student>> studentsLiveData = new MutableLiveData<>();

    public RealmServiceModel(RealmService mRealmService) {
        this.mRealmService = mRealmService;
    }

    public MutableLiveData<List<Student>> students(){
        return this.studentsLiveData;
    }

    public void fetchAllStudent(){
        progress.postValue(true);
        mRealmService.findAllStudent()
                .delay(2, TimeUnit.SECONDS)
                .subscribe(students -> {
                     progress.postValue(false);
                     studentsLiveData.postValue(students);
                });
    }

    public void addStudent(){
        this.progress.postValue(true);

        Student a = new Student();
        a.setAge(16);
        a.setAddress("中国上海");
        a.setName("陈永和");

        this.mRealmService.addStudent(a)
                .delay(1,TimeUnit.SECONDS)
                .subscribe(()->this.progress.postValue(false));

    }

    public void removeStudents(){
        this.progress.postValue(true);
        this.mRealmService.deleteAllStudent()
                .delay(1,TimeUnit.SECONDS)
                .subscribe(()->this.progress.postValue(false));

    }
}

3.4 类务工厂类

这个类主要是用来生成modle的实例

public class RealmServiceModelFactory implements ViewModelProvider.Factory  {

    private final RealmService mRealmService;
    @Inject
    public RealmServiceModelFactory(RealmService mRealmService) {
        this.mRealmService = mRealmService;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        return (T)new RealmServiceModel(mRealmService);
    }
}

四、UI界面

在Activity中通过依赖注入调用业务逻辑类


public class MVVMActivity extends AppCompatActivity implements OnClickListener {

    private TextView mask;
    private LinearLayout container;

    RealmServiceModel mRealmServiceModel;

    @Inject
    RealmServiceModelFactory mRealmServiceModelFactory;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //这里是重点,需要注入
        AndroidInjection.inject(this);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vvm);

        mRealmServiceModel = ViewModelProviders.of(this,mRealmServiceModelFactory).get(RealmServiceModel.class);

        this.mask = this.findViewById(R.id.mask);
        this.container = this.findViewById(R.id.container);

        this.findViewById(R.id.query).setOnClickListener(this);
        this.findViewById(R.id.add).setOnClickListener(this);
        this.findViewById(R.id.clear).setOnClickListener(this);

        //进度条显示和隐藏
        mRealmServiceModel.progress().observe(this,this::progress);
        //异常信息提示
        mRealmServiceModel.error().observe(this,this::error);
        //学生数据更新
        mRealmServiceModel.students().observe(this,this::onStudentsChanged);
    }

    public void progress(boolean show){
        this.mask.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    public void error(String error){
        Toast.makeText(this,error,Toast.LENGTH_LONG).show();
    }

    /**
     * 查询所有学生数据,并更新界面
     */
    public void onStudentsChanged(List<Student> students) {
        container.removeAllViews();
        for (Student s : students) {
            container.addView(buildTextView(s.toString()));
        }
    }

    public TextView buildTextView(String text) {
        TextView txt = new TextView(this);
        txt.setText(text);
        txt.setTextColor(Color.BLACK);
        txt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        txt.setLayoutParams(lp);
        return txt;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add:
                this.mRealmServiceModel.addStudent();
                break;
            case R.id.query:
                this.mRealmServiceModel.fetchAllStudent();
                break;
            case R.id.clear:
                this.mRealmServiceModel.removeStudents();
                break;
        }
    }


}

五、依赖注入DI

5.1 Module依赖注入

@Module
public class RealmServiceModule {
    @Provides
    public RealmServiceModelFactory provideRealmServiceModelFactory(RealmService realmService){
        return new RealmServiceModelFactory(realmService);
    }

    @Provides
    RealmService provideRealmService() {
        return new RealmService();
    }
}
5.2 BuildersModule

这个主要是建立Activity和module的联系,是一个枢纽中心
先定义一个通用的注解

    @Scope
    @Retention(RUNTIME)
    public @interface ActivityScope {
    }

然后编写BuildersModule,建立Activity和Module的联系

@Module
public abstract class BuildersModule {

    @ActivityScope
    @ContributesAndroidInjector(modules = RealmServiceModule.class)
    abstract MVVMActivity bindMVVMActivityModule();

}
5.3 AppComponent

这种写法是Dagger2的最新的用法,具体详情需要去了解Dagger2的使用了.

@Singleton
@Component(modules = {
        BuildersModule.class,
        AndroidSupportInjectionModule.class,
        RealmServiceModule.class })
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(RealmApp app);
        AppComponent build();
    }
    void inject(RealmApp app);
}
5.4 Application

最后一步要建立Activity生命周期和各个Module的关系,这样可以自动在onDestroy中销毁对象

public class RealmApp extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        //数据库相关的初始化
        Realm.init(this);
        RealmConfiguration configuration = new RealmConfiguration.Builder()
                .name("realm.realm")
                .schemaVersion(1)
                .build();
        Realm.setDefaultConfiguration(configuration);

        //自动生成的DaggerAppComponent类,调用方法初始化
        DaggerAppComponent
                .builder()
                .application(this)
                .build()
                .inject(this);

    }


    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值