因为工作经历的关系,做框架搭建工作至今已经7年了,进过一轮轮的演变和优化,才有现在QAndroid的原型。之前一直觉得不完美,针对性太强所以一直没有开源。后来了解到飞信、苏宁、优信他们的框架,感觉还不如QAndroid,所以才有了这篇文章。
QAndroid特别适合中小项目,目前已在多个项目中应用;他是一个简单小巧、开发快速并且维护简单的android app开发框架。基于DataBinding,使用kotlin开发跟迅捷。 框架已经集成okhttp、glide、fastjson和友盟统计。
推荐使用mvvm模式,只需要开发维护model和xml两个文件即可。
github地址:https://github.com/ddoolcg/QAndroid
将其添加到存储库末尾的根build.gradle中:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
添加依赖项
// kotlin android插件
apply plugin: 'kotlin-android'
// kotlin的apt(编译时生成代码)
apply plugin: 'kotlin-kapt'
// 通过解析xml直接使用view,感兴趣的可以自行百度
//apply plugin: 'kotlin-android-extensions'
android {
...
//开启dataBinding
dataBinding {
enabled true
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
// QAndroid依赖
api 'com.github.ddoolcg:QAndroid:1.4.1'
// databinding注解依赖,编译时生成代码
kapt 'com.android.databinding:compiler:3.1.4'
}
UIUtils工具类需要初始化、自定义http认证(也可以继承BaseApplication实现)
@Override
public void onCreate() {
super.onCreate();
if (UIUtils.init(this)) onInitMainProcesses();
Token.INSTANCE.init("token", new Function1() {
@Override
public Unit invoke(Boolean aBoolean) {
gotoLoin(aBoolean);
return null;
}
});
}
联网调用
//lambda不支持泛型套泛型的解析方式
DataEntry("url").joinProgressDialog(activity).formBody(map).post {TODO()}
//抽象方法实现的方式调用,支持泛型套泛型的解析方式
DataEntry("url").joinProgressDialog(activity).formBody(map).post(OnSuccessListener)
//默认统一处理接口调用失败
DataEntry.failDefault={code,data-> }
SharedPreferences操作
操作类
PreferenceKTX
多次put采用Any扩展
preferenceEdit {
putBoolean()
putString()
}
view的一些实用扩展
doOnGlobalLayout
view.doOnGlobalLayout {
if (Boolean) {
action()
true
} else {
false
}
}
doOnPreDraw
view.doOnPreDraw {
action()
}
ViewGroup
viewGroup += view//addView
viewGroup -= view//removeView
页面实现demo(登陆)
activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView(this, R.layout
.activity_login)
val login = Login(this).apply {
titleText = "登陆"
isShowBack = false
}
binding.login = login
}
xml:
model:
class Login(activity: BaseActivity) : BaseObservableMe(activity) {
@get:Bindable
var username: String = ""
set(username) {
field = username
notifyPropertyChanged(BR.username)
}
@get:Bindable
var password: String = ""
set(password) {
field = password
notifyPropertyChanged(BR.password)
}
fun login(view: View) {
if (!check())
return
val map = hashMapOf("username" to username, "password" to MD5.GetMD5Code(password))
DataEntry(HttpUrl.login).joinProgressDialog(activity).formBody(map).post {
saveToken(it.token)
PreferenceKTX.setConfig(it)
try {
val clazz: Class = Class.forName("com.lcg.expressbus.MainActivity") as Class
activity.startActivity(clazz)
activity.finish()
} catch (e: Exception) {
throw RuntimeException("com.lcg.expressbus.MainActivity is error!")
}
}
}
/**去注册*/
fun gotoRegister(view: View) {
RegisterActivity.start(activity)
}
/**去密码重置*/
fun gotoResetPassword(view: View) {
TODO()
}
protected open fun check(): Boolean {
when {
TextUtils.isEmpty(this.username) -> {
UIUtils.showToastSafe("用户名不能为空")
return false
}
!this.username.isPhone() -> {
UIUtils.showToastSafe("请输入一个有效手机号码")
return false
}
TextUtils.isEmpty(this.password) -> {
UIUtils.showToastSafe("密码不能为空")
return false
}
this.password.length < 2 -> {
UIUtils.showToastSafe("密码必须大于两位")
return false
}
else -> return true
}
}
}
开启友盟统计
在AndroidManifest.xml文件中修改
DataEntry无法满足你的需求可参考:
正常和异常数据都是通过200请求返回的
扩展联网框架