为了开发效率,记录一下自己的开发框架,整体使用mvvm的模式,使用android自带的databinding开发数据驱动的页面逻辑。
android架构框架设计-LMLPHP
大致分为几个部分,common存放一般在各个模块都会用到的类,module是项目模块,主要是业务模块,如user用户模块,user下有有三个包ui/model/viewCtrl ui存放该模块下的Activity,viewCtrl存放的是业务处理逻辑类,用过databinding的都知道,databing可以绑定类,viewCtrl就是界面视图的逻辑类,model存放数据模型。network是网路框架,utils是工具包,views是自定义的view
github地址:temp模板地址
项目适配的方案是以限定符进行适配,以screeMatch工具批量生成。参考
项目中所用到三方库:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.zjhc.jxzq.temp"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }
    dataBinding {
        enabled = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildTypes {
                release {
                    //是否开启zip优化
                    zipAlignEnabled true
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                    applicationVariants.all { variant ->
                        variant.outputs.all { output->
                            def outputFile = output.outputFile
                            def fileName
                            if(outputFile != null && outputFile.name.endsWith('.apk')){
                                if(variant.buildType.name.equals('release')){
                                    fileName = "App${defaultConfig.versionName}.apk"
                                }else if(variant.buildType.name.equals('debug')){
                                    fileName  =  "App${defaultConfig.versionName}_debug.apk"
                                }
                                outputFileName = fileName
                            }

                        }
                    }
                }
            }
        }
    }

}

dependencies {

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    compile 'com.android.support:design:27.1.1'
    //ARouter
    annotationProcessor 'com.alibaba:arouter-compiler:1.1.2'
    compile 'com.alibaba:arouter-api:1.2.1'
    //底部导航栏
    implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.3'
    //沉浸式布局
    compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
    //retrofit+rxjava
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
    compile 'io.reactivex.rxjava2:rxjava:2.1.0'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    //gson
    compile 'com.google.code.gson:gson:2.8.0'
    //mvvm的recycleview的封装
    compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:2.1.0'
    compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:2.1.0'
    //强大的 RecyclerView 适配器
    compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'
    //glide
    implementation 'com.github.bumptech.glide:glide:3.5.2'
    //SwipeToLoadLayout 下拉刷新控件
    compile 'com.github.Aspsine:SwipeToLoadLayout:1.0.4'
}

项目中使用ARouter框架进行页面跳转,注意,ARouter的路径必须两级以上。
框架中的重点是对于网络和列表加载的封装,网路参考这篇参考

//列表使用方法
 <data>
        <import type="me.tatarka.bindingcollectionadapter2.LayoutManagers" />
        <variable
            name="viewCtrl"
            type="com.zjhc.jxzq.jxzq.module.home.viewCtrl.SearchCompanyCtrl" />
    </data>
 <com.aspsine.swipetoloadlayout.SwipeToLoadLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:listener="@{viewCtrl.listener}">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/swipe_target"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:addItemDecoration="@{viewCtrl.viewModel.type}"
                app:itemBinding="@{viewCtrl.viewModel.onItemBind}"
                app:items="@{viewCtrl.viewModel.items}"
                app:layoutManager="@{LayoutManagers.linear()}" />
        </com.aspsine.swipetoloadlayout.SwipeToLoadLayout>

在框架中大量使用了自定义属性BindingAdapter,app:listener实现了下拉刷新,上拉加载的方式, app:addItemDecoration实现了列表的分隔符,app:itemBinding绑定item布局, app:items绑定数据源, app:layoutManager实现列表布局方式。参考
项目中对于应用生命周期的管理在MyApplication中实现:

this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                addActivity(activity);
            }

            @Override
            public void onActivityStarted(Activity activity) {
            }

            @Override
            public void onActivityResumed(Activity activity) {
                if(mActivity == null){
                    mActivity = activity;
                }else{
                    if(mActivity != activity){
                        mActivity = activity;
                    }
                }
            }

            @Override
            public void onActivityPaused(Activity activity) {
            }

            @Override
            public void onActivityStopped(Activity activity) {
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
                removeActivity(activity);
            }
        });
        //添加actiivty
    public void addActivity(Activity actiivty){
        if(!activityList.contains(actiivty)){
            activityList.add(actiivty);
        }
    }
    //销毁单个Activity
    public void removeActivity(Activity activity){
        if(activityList.contains(activity)){
            activityList.remove(activity);
        }
    }
    //销毁所有的activity
    public static  void removeAllActivity(){
        for(Activity activity :activityList){
            activity.finish();
        }
    }

以lifecycle管理生命周期,在Activity创建时添加,如果需要每次打开手势验证,可以对存储的activity进行进行判断,是否加载手势页。注意,使用dialog的时候请勿使用application中存储的activity,因为页面的不可见会导致dialog创建失败。
为了项目的性能与调试,统一管理项目的常量属性存储于BaseParm和Constant中。为了后期维护,主要勤写注释,类的使用需要注明类的用途,单层调用可以写上{@link 调用它的类} 以link链接到调用此类的方法便于调试。

/**
 * @Author 作者
 * @Date 2018/7/6.
 * @Description 类的作用
 * {@link 类名 }
 */
07-12 06:53