一个C#开发搭建Android框架的心路历程
前言
Java框架实在是太多了,因为是初学乍练,所以,只好以百度为标准选择框架了。
Java的框架文章太难写了,因为他引用了太多框架,而没一个框架都有很繁琐的配置,把每个框架都写一遍,就等于写书了;所以本文只能大体上介绍,但大体上介绍,感觉读起来又没有生气,总之非常难写。
新建项目
首先新建项目KibaFramework,不要勾选use legacy android.support libraries。
项目结构
数据库:xUtils3,这里只使用xutils3来管理sqlite数据库。
页面元素获取:butterknife,dataBinding,主要使用butterknife;dataBinding只是提供一种额外的元素获取模式。
UI框架:XUI、XPage,这个框架的模式非常好,因为是一个人写的,比一个团队写的组合功能更合理,还有demo可以参考。
辅助语言:Kotlin,我觉得Kotlin中的很多语法很好用,很简便,比如定义实体就非常好用,在大方向使用Java的情况下,辅助使用Kotlin定义一些单独的文件,很方便。
项目配置
build.gradle—Project
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.0"
ext.anko_version = "0.10.8"
repositories {
google()
mavenCentral()
jcenter()
maven { url "https://jitpack.io"}
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
maven { url 'https://jitpack.io' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradl—App
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.vanpeng.survey"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk{
abiFilters "armeabi-v7a"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
implementation 'de.gerdi-project:GSON:6.0.6'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation "org.jetbrains.anko:anko-commons:$anko_version" // Anko Commons
implementation "org.jetbrains.anko:anko-sdk25:$anko_version" // Anko Layouts sdk15, sdk19, sdk21, sdk23 are also available
implementation "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version" // Coroutine listeners for Anko Layouts
implementation "org.jetbrains.anko:anko-sqlite:$anko_version" // Anko SQLite implementation 'org.xutils:xutils:3.3.36'
implementation "com.squareup.okhttp3:okhttp:4.9.0"
implementation 'com.google.code.gson:gson:2.8.6'
//解决超过65546代码的问题
implementation 'com.android.support:multidex:1.0.2'
implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4"
implementation 'com.jakewharton:butterknife:10.2.3'
//ButterKnife
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
//XUI框架
implementation 'com.github.xuexiangjys:XUI:1.1.8'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
//工具类
implementation 'com.github.xuexiangjys.XUtil:xutil-core:2.0.0'
implementation 'com.github.xuexiangjys.XUtil:xutil-sub:2.0.0'
//侧边栏菜单
implementation 'com.yarolegovich:sliding-root-nav:1.1.1'
//下拉刷新
implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' //核心必须依赖
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-header:1.1.5'
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-layout:1.1.5'
//预加载占位控件
implementation 'me.samlss:broccoli:1.0.0'
//XPage页面框架
implementation 'com.github.xuexiangjys.XPage:xpage-lib:3.1.1'
annotationProcessor 'com.github.xuexiangjys.XPage:xpage-compiler:3.3.0'
//如果是androidx项目,使用1.1.0版本及以上
implementation 'com.github.xuexiangjys.XAOP:xaop-runtime:1.1.0'
}
gradle.properties
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.enableJetifier=true
项目编写
首先编写BaseActivity和BaseFragment,分别继承XUI和XPage下的XPageActivity和XPageFragment。
然后编写一些常用的函数在,比如弹出对话框。
然后编写MyApplication,在MyApplication里注入Xui和xUnit。
XUI.init(this); //初始化UI框架
XUI.debug(true); //开启UI框架调试日志
x.Ext.init(this);
x.Ext.setDebug(BuildConfig.DEBUG); // 开启debug会影响性能
然后在配置一些静态属性,比如要请求的Api的网址。
最后封装一些常用的工具类,就可以开发编写Activity了。
SplashActivity:初始启动页面,进行一个渐变的动画展示,然后通过xUint初始化数据库,然后跳转到登录页面。
LoginActivity:登录页面,通过Http通讯发送登录请求。
MainActivity:首页,实现一个左侧滑动菜单,和一个fragment的切换内容页。
编写完Activity后,在manifest里增加权限,并且手动加Activity,因为要设置它的launchMode和其他属性。
manifest如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kiba.framework">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Framework">
<activity
android:name=".activity.main.MainActivity"
android:label="主页"
android:screenOrientation="landscape"
android:launchMode="singleTask"
android:theme="@style/Theme.Framework.NoActionBar"></activity>
<activity
android:name=".activity.protocol.ProtocolActivity"
android:label="协议内容"
android:screenOrientation="landscape"
android:launchMode="singleTask" />
<activity
android:name=".activity.login.LoginActivity"
android:label="登录"
android:screenOrientation="landscape"
android:launchMode="singleTask"
android:theme="@style/Theme.Framework.NoActionBar" />
<activity
android:name=".SplashActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:launchMode="singleTask"
android:theme="@style/Theme.Framework.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
修改themes.xml,注意要让Theme.Framework继承XUITheme.Phone,不然将无法解析XUI框架里自定义属性的默认值。
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Framework" parent="XUITheme.Phone">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryVariant">@color/movebule</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="Theme.Framework.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.Framework.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="Theme.Framework.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
关于页面样式
页面样式我也不擅长,所以这里基本上以复制开源项目的样式为主。
登录界面效果:
主页面效果图
XUI简单介绍
XUI是一个非常好用的框架,他重新封装了Activity和Fragment,让整体的代码逻辑更合理了。
使用时,我们可以让BaseActivity和BaseFragment继承XPageActivity和XPageFragment,需要注意的是BaseActivity和BaseFragment需要为抽象类,代码如下:
BaseActivity
public class BaseActivity extends XPageActivity {
//返回值【/storage/emulated/0/Android/data/com.kiba.framework/files】
public String FilesPath_External;
//返回值【/storage/emulated/0】
public String FilesPath_Internal;
public Context baseContext;
public DbManager.DaoConfig daoConfig;
@Override
protected void onCreate(Bundle savedInstanceState) {
FilesPath_External = getExternalFilesDir("").getAbsolutePath();
FilesPath_Internal = Environment.getExternalStorageDirectory().getPath();
super.onCreate(savedInstanceState);
baseContext = this;
MyApplication.activityList.add(this);
}
}
BaseFragment
public abstract class BaseFragment extends XPageFragment { //返回值【/storage/emulated/0/Android/data/com.kiba.framework/files】
public String FilesPath_External;
//返回值【/storage/emulated/0】
public String FilesPath_Internal;
@Override
protected void initPage() {
FilesPath_External = this.getActivity().getExternalFilesDir("").getAbsolutePath();
FilesPath_Internal = Environment.getExternalStorageDirectory().getPath(); }
}
继承的Activity需要继承getLayoutId和onCreate,代码如下:
public class LoginActivity extends BaseActivity { //XUI的绑定页面的模式
@Override
protected int getLayoutId() {
return R.layout.activity_login;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
}
}
继承的Fragment需要重载getLayoutId和initViews,需要在类上加@Page注解,代码如下:
@Page(name = "其他")
public class OtherFragment extends BaseFragment {
@Override
protected int getLayoutId() {
return R.layout.fragment_other;
}
@Override
protected void initViews() {
TitleBar titleBar = super.initTitle();
}
}
我们也可以不重载getLayoutId,自己在onCreate或中initViews中找视图填充。
final View view = View.inflate(this, R.layout.activity_splash, null);
setContentView(view);
结语
Java的框架真的实在是太多了,而且每一个的内容真都很多,这真的是一个需要大量时间熟悉和学习的语言。
需要学习Java基础的可以参考一下我的Java短篇文章
本文主要代码来自于开源框架XUI的Demo。
https://github.com/xuexiangjys/XUI
----------------------------------------------------------------------------------------------------
到此,使Android框架就已经介绍完了。
代码已经传到Github上了,欢迎大家下载。
Github地址:https://github.com/kiba518/AndroidFramework
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!
https://www.cnblogs.com/kiba/p/15480140.html
一个C#开发搭建Android框架的心路历程的更多相关文章
- 一个C#开发编写Java框架的心路历程
前言 这一篇絮絮叨叨,逻辑不太清晰的编写Java框架的的一个过程,主要描述我作为一个java初学者,在编写Java框架时的一些心得感悟. 因为我是C#的开发者,所以,在编写Java框架时,或多或少会带 ...
- 从零开始搭建android框架系列(转)
网址:从零开始搭建android框架系列 githup:https://github.com/CameloeAnthony/Ant
- 【Android 系统开发】Android框架 与 源码结构
一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...
- 一个C#开发者学习SpringCloud搭建微服务的心路历程
前言 Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘. SpringClou ...
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
最近出去面试,总会被问到我们项目现在采用的什么开发框架,不过据我的经验网络框架(volley)+图片缓存(uIl)+数据库(orm)+mvp,不过现在这套框架比较好了,现在采用什么呢?Rxjava + ...
- Android网络请求心路历程
HTTP请求&响应 既然说从入门级开始就说说Http请求包的结构.一次请求就是向目标服务器发送一串文本.什么样的文本?有下面结构的文本.HTTP请求包结构 例子: 1 2 3 4 5 6 7 ...
- Android基础之用Eclipse搭建Android开发环境和创建第一个Android项目(Windows平台)
一.搭建Android开发环境 准备工作:下载Eclipse.JDK.Android SDK.ADT插件 下载地址:Eclipse:http://www.eclipse.org/downloads/ ...
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
- 搭建Android开发环境附图详解+模拟器安装(JDK+Eclipse+SDK+ADT)
——搭建android开发环境的方式有多种,比如:JDK+Eclipse+SDK+ADT或者JDK+Eclipse+捆绑好的AndroidSDK或者Android Studio. Google 决定将 ...
随机推荐
- CodeForce-782B The Meeting Place Cannot Be Changed(高精度二分)
https://vjudge.net/problem/CodeForces-782B B. The Meeting Place Cannot Be Changed time limit per tes ...
- 【OI】竖式问题分析与解答
题目:找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合.输入数字集合(相邻数字之间没有空格),输出所有竖式.每个竖式前应有编号,之后应有一个空行 ...
- 手把手教你实现栈以及C#中Stack源码分析
定义 栈又名堆栈,是一种操作受限的线性表,仅能在表尾进行插入和删除操作. 它的特点是先进后出,就好比我们往桶里面放盘子,放的时候都是从下往上一个一个放(入栈),取的时候只能从上往下一个一个取(出栈), ...
- Java 知识点 列表
* Java SE Java开发基础 Java异常处理 Java泛型与反射 Java IO基础 JUnit单元测试 Java多线程开发 Maven基础 https://www.yiibai.com/ ...
- WireShark新手使用教程
Wireshark是非常流行的网络封包分析软件,可以截取各种网络数据包,并显示数据包详细信息.常用于开发测试过程各种问题定位.本文主要内容包括: 1.Wireshark软件下载和安装以及Wiresha ...
- 关于cgroup的几个核心名词及其关系
子系统(subsystem) 所谓子系统可以理解为操作系统里的各种资源(组件),如CPU,内存,磁盘,网卡(带宽) 层级(Hierarchies) 所谓层级就是子系统的集合,又 ...
- Linux服务器时间同步配置
Linux服务器时间同步配置 以CentOS7 做时间服务器,其他服务器(Centos 6.RHEL7)同步该服务器时间 RHEL 7.CentOS 7 默认的网络时间协议 为Chrony 本教程 ...
- 智汀家庭云-开发指南Golang:设备模块
1.品牌 品牌指的是智能设备的品牌,SA通过插件的形式对该品牌下的设备进行发现控制.理论上来说一个品牌对应一个插件服务.您可以通过项目 根目录下的品牌查看SA支持的品牌.关于插件服务的详细信息可以参考 ...
- virtualbox nat 模式下连接虚拟机redis
主要是使用端口转发的方法 如果你能使用xshell等工具连接这个方法基本一样 接着修改redis.conf文件的69 行(我使用的是5.0)将这里的地址修改为虚拟机的 ip 地址,这里我使用的是备份 ...
- T-SQL——关于表数据的复制插入
目录 0. 复制表中一列插入到另外一列 1. 复制表结构和数据到自动创建的一张新表中--select into 2. 复制表中一些字段值插入到另外一张表中--insert into 3. 将存储过过程 ...