Android项目框架搭建(一)

article/2025/10/5 23:09:15

本篇先记录下当前项目中涉及的主要技术要点。也算是对所作项目的一次总结。如果这个过程能对你有些许的帮助,那可能就显得有意义点了。

一个完整的Android项目会涉及后台和前端。我们只关注于前端,也就是我们的app本身。

下面列出项目架构需要具备的技术点。(以当前所作项目为例)
1.项目结构(MVP设计模式)
2.屏幕适配
3.程序启动页
4.运行权限获取
5.基类(BaseActivity/BaseFragment/BaseApplication)
6.Retrofit(最流行的网络请求框架)+RxJava(链式编程风格+异步)
7.程序崩溃界面处理

1.项目结构

在这里插入图片描述
项目采用MVP设计架构。
关于MVC,MVP,MVVM设计模式的升级改造做如下说明:

MVC模式:
M 指模型层(网络IO、文件IO等操作)
V 指视图层(对应Android中的Layout和Activity/Fragment)
C 指控制层(对应Android中的Activity/Fragment)

在Android中,Activity/Fragment既充当控制层又充当视图层,这就导致了V和C这两层耦合在一起,当业务比较复杂时,Activity/Fragment文件就很庞大,导致难以维护和测试,于是MVP模式便应用而生。

MVP模式:
M 指模型层(同MVC)
V 指视图层(同MVC)
P 指业务层(业务逻辑)

Activity/Fragment只充当视图层,不做任何的业务逻辑,将业务逻辑全部放在业务层,由Presenter和Model进行交互,避免Model直接操作View。MVP的优点:将业务从Activity/Fragment分离,便于后期维护和测试。MVP使用特点是面向接口编程(View/Presenter/Model都定义一套接口)。可以说MVP模式的出现主要是将MVC中Control控制层进行解耦,View-视图层中需要展示数据则通过Present-业务层调用Model-模型层去获取,Present-业务层拿到数据后以接口形式回传给View-视图层View-视图层只需要注册监听Present-业务层用于更新View-视图层的接口就行了。

关于MVC和MVP的区别,大家可以参考 Android中MVC/MVP模式区别 ,里面介绍的很清楚,简单易懂。

有了MVP就够了,为什么又出来了一个MVVM呢?
关于MVP和MVVM模式的区别,网上资料多而杂,看过一圈之后,你可能会感觉更晕了。这个时候你可以继续往下看我的总结。

MVC和MVVM的唯一区别就是MVVM中多了一个DataBinding,其他基本无差别。
DataBinding 是谷歌官方发布的一个框架,顾名思义即为数据绑定,是 MVVM 模式在 Android 上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。MVVM 相对于 MVP,其实就是将 Presenter 层替换成了 ViewModel 层。DataBinding 能够省去我们一直以来的 findViewById() 步骤,大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout 文件中。

关于DataBinding框架你可以参考 Android DataBinding 从入门到进阶,但是我没有在项目中使用。尝试用了一下,发现不好用。

原因如下:
第一条,DataBindding优势在于支持数据绑定(单向和双向),这意味着MVP模式中Present-业务层通过接口回调的方式来通知View-视图层来进行界面更新操作流程不存在了,取而代之的是通过标签绑定的形式来进行更新。如此,layout.xml中可能会进行一些简单的业务逻辑处理。虽然是简单的业务逻辑,我还是感觉和我们一致提倡的视图&&业务分离的理念相悖。

第二条,.使用DataBinding不方便维护。我曾尝试将MVP模式的项目代码改为DataBinding+MVVM的实现方式。结果很是不爽。举个例子,在使用DataBinding设置监听事件的时候,对点击事件的引用是不会进行错误提示的,一旦你定义的名字和实际引用的存在大小写不匹配的情况,很难排查出错点。Android IDE对代码补全的支持还不是很友好。

3.使用DataBinding的使用率不是很高。别的我不知道,我身边的人也仅限于了解过活着写过简单的Demo去学习其用法。但是实际项目中没有用到。因此使用DataBinding的话还需谨慎,如果多人维护同一个项目的话,那么大家都会DataBinding的使用,不然日后维护绝对是个坑。

4.网上介绍的关于DataBinding的用法的介绍,我不想吐槽。好多都是直接复制粘贴过来的,都是些基本的不能再基本的用法,高级用法介绍的很少。有些连基本用法都没讲清楚。比如,我们经常在layout.xml中来使用include来进行布局的复用(虽然不能减少层级嵌套),但是在include中的Layout中使用clickListener的时候,需要由父布局层层传递下去,才能起作用。但是这种很重要的用法,有些文章连提都没提。

算了,不吐槽了。不然该有小伙伴拿“存在即合理”来反驳我了。

当项目界面比较复杂控件比较多的时候,可能会需要写大量的findById(R.id.xxx),如果你看着别扭的话,可以使用开源库Butterknife(黄油刀)来进行替换。不一定要使用DataBindding。算了,你们还是自己回头在实际项目中用一下吧,如果你们觉得好用,麻烦告诉我以下,我们再交流交流。

如果对于MVC/MVP设计架构不清楚的话,推荐大家阅读:
Android App的设计架构:MVC,MVP,MVVM与架构经验谈,文章中有段话说的特别好:

刚开始理解这些概念的时候认为这几种模式虽然都是要将view和model解耦,但是非此即彼,没有关系,一个应用只会用一种模式。后来慢慢发现世界绝对不是只有黑白两面,中间最大的一块其实是灰色地带,同样,这几种模式的边界并非那么明显,可能你在自己的应用中都会用到。实际上也根本没必要去纠结自己到底用的是MVC、MVP还是MVVP,不管黑猫白猫,捉住老鼠就是好猫。

通俗表述就是,不要刻意的是自己的代码故意去迎合某种设计模式,而是通过这种"视图&&业务逻辑解耦"的思想去引贯穿和引导自己去写代码。

 

2.屏幕适配

在这里插入图片描述
前面受限于截图,特此将values/dimens.xml文件展开如上图。android项目开发,屏幕适配是首先要考虑的问题关于屏幕适配,大家可参照另一篇文章:
Android 屏幕适配方案
 

3.程序启动页

AndroidMantifest.xml

...<activityandroid:name=".ui.activity.HRSplashActivity"android:theme="@style/SplashTheme"android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
...
  <!-- Base application theme. --><style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar"><!-- Customize your theme here. --><item name="colorPrimary">#00FFFF</item><item name="colorPrimaryDark">#FFFFFF</item><item name="colorAccent">#FFFF00</item><item name="android:windowBackground">@mipmap/startup</item><item name="android:windowActionBar">false</item><item name="android:windowNoTitle">true</item></style>

上述中的

 <item name="android:windowBackground">@mipmap/startup</item>

就是启动页的图。
 
HRSplashActivity.java

public class HRSplashActivity extends FragmentActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);//todo:可在此处添加关于启动页面的延时操作eg(延时2s): try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}startActivity(new Intent(HRSplashActivity.this, HRLoginActivity.class));finish();}}

 

4.运行权限获取

正常情况下程序运行的流程图下:
启动页----->登录页----->程序首页
没错,但是在从启动页跳转到登录页的时候,涉及到权限授予,主要是针对Android 6.0权限的授予。也许你会问,我在用到权限的时候再申请不行么? 答案是:可以,但是不建议。如果如果只有少量界面需要申请权限,即用即申请是可以的。但是如果需要权限的界面很多,这就比较麻烦了-------我们需要在每个界面都要判断所需权限是否已经授予了,如果没有的话就继续申请。权限申请逻辑比较分散,不便于后续维护。

因此最好的办法就是在程序开启时就要进行权限申请,如果所需权限没有全部被授予**(记住:所需权限必须全部被授予)**,就不允许用户登录。事实上QQ就是这么做的,当权限被用户手动拒绝之后,会弹出提示框,从而引导用户去设置中手动设置。

废话不说,直接贴出权限工具类,这个工具类其实还有些别的权限相关的方法,怕影响阅读,我把它阉割掉了,如果想看完整的,也可移步
Android常用的工具类汇总(方便日后使用)
PermissionUtils .java

public final class PermissionUtils {/*** Return whether <em>you</em> have granted the permissions.** @param permissions The permissions.* @return {@code true}: yes<br>{@code false}: no*/public static boolean isGranted(final String... permissions) {for (String permission : permissions) {if (!isGranted(permission)) {return false;}}return true;}private static boolean isGranted(final String permission) {return Build.VERSION.SDK_INT < Build.VERSION_CODES.M|| PackageManager.PERMISSION_GRANTED== ContextCompat.checkSelfPermission(Utils.getApp(), permission);}/*** Launch the application's details settings.*/public static void launchAppDetailsSettings() {Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");intent.setData(Uri.parse("package:" + Utils.getApp().getPackageName()));Utils.getApp().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));}/*** 批量申请权限(如果当前没有权限的话)。授权结果在onRequestPermissionsResult中处理*/public static void requestPermissionsIfNeed(Activity activity, String[] perms, int requestCode) {if (perms.length == 0) {return;}HashSet<String> needPerms = new HashSet<>();for (String perm : perms) {if (!isGranted(perm)) {needPerms.add(perm);}}if (needPerms.size() == 0) {return;} else {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {activity.requestPermissions(needPerms.toArray(new String[needPerms.size()]), requestCode);}}}}

上述保留了最基本的权限申请逻辑,完全能满足需求。

至于怎么在程序入口处调用,很简单,看程序入口。
HRLoginActivity.java

public class HRLoginActivity extends HRBaseActivity implements View.OnClickListener {private final int PERMISSION_REQUEST_CODE = 0x183;private final String perms[] = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.MODIFY_AUDIO_SETTINGS,Manifest.permission.INTERNET,Manifest.permission.ACCESS_WIFI_STATE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO,Manifest.permission.CHANGE_NETWORK_STATE};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestPermissions();............}private void requestPermissions() {PermissionUtils.requestPermissionsIfNeed(this, perms, PERMISSION_REQUEST_CODE);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.login_confirm:if (PermissionUtils.isGranted(perms)) {login();} else {requestPermissions();}break;default:break;}}/*** 某一权限没有被授予,弹出提示框*/private void showPermissionDialog() {AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("温馨提示").setMessage("请在设置中开启所需权限,以正常使用xxx功能").setNeutralButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();finish();}}).setNegativeButton("去设置", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();PermissionUtils.launchAppDetailsSettings();finish();}});final AlertDialog dialog = builder.show();dialog.setCanceledOnTouchOutside(false);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode != PERMISSION_REQUEST_CODE) {return;}for (int i = 0; i < grantResults.length; i++) {if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {showPermissionDialog();return;}}}}

逻辑很简单:如果权限没授予,就弹出提示框,引导用户去“设置”中手动授予权限,如果在弹框中点击“取消”,则退出程序。下次进来,依旧如此,直至所有权限全部被授予。

 
好了,先到这吧,下面的3条将会在下一篇 Android项目框架搭建(二) 中进行介绍。

5.基类(BaseActivity/BaseFragment/BaseApplication)
6.Retrofit(最流行的网络请求框架)+RxJava(链式编程风格+异步)
7.程序崩溃界面处理

请先让我酝酿一下。

 
 
 
附上链接:
Android项目框架搭建(二)


http://chatgpt.dhexx.cn/article/dAv4CQhT.shtml

相关文章

创建安卓项目工程

安卓项目工程 前言一创建工程的步骤newproject找到empty配置相关信息创建成功 二、项目相关的文件1.llayoyt文件这个文件位于app\src\res\layout它运行的结果是&#xff0c;这个APP如果在手机上运行的话&#xff0c;会是什么样的界面 前言 说清楚这么创建一个安卓工程 并且运行…

2.Android Studio创建安卓项目及项目结构

-----------android培训、java培训、java学习型技术博客、期待与您交流&#xff01;------------ 上一篇Android Studio搭建完成了&#xff0c;接下来我们就用Android Studio创建我们的安卓项目吧&#xff01; 目录&#xff1a; 一、使用Android Studio 图形用户界面创建安卓工…

Android项目结构

Android项目结构 新建个空的安卓项目&#xff0c;打开&#xff0c;切换到project模式&#xff1a; 一、工程结构 1/ .gradle和.idea 这两个目录下都是AS自动生成的&#xff0c;无须关心&#xff0c;也不要手动编辑。 2/ app 项目中的代码、资源等几乎都在这里&#xff0c;…

Android项目工程目录简介

主工程目录&#xff1a; 一、.gradle 此文件夹是构建工具 Gradle 的配置文件夹&#xff0c;也会存储一些项目的构建缓存信息&#xff0c;在首次build项目时&#xff0c;会根据配置文件去下载这些文件&#xff0c;此文件夹是自动生成的文件夹&#xff0c;我们无需关心里面的内容…

Android创建项目

目录 创建Android项目 配置项目结构 创建安卓模拟器 模拟器运行 HelloWorld 应用 真机运行 HelloWorld 应用 创建Android项目 打开 Android studio 工具&#xff0c;选择Project&#xff0c;选择 New Project 由于现在是教程博客&#xff0c;所以我们随便选择 一个 空 Ac…

Android Studio创建安卓项目工程

Android Studio创建安卓项目工程 前言 因为想抽出时间复习考研因此提前接触安卓的一些开发&#xff0c;在实训的时候就可以不用再听讲学习&#xff0c;节省时间 随着前端混合开发和小程序技术的兴起&#xff0c;安卓开发的需求在日益减少。更多的学习是出于兴趣的缘故吧。 创…

八个Android项目源码

Android项目源码分享 给大家分享几个Android开发项目源码&#xff0c;大部分功能相信可以在实战项目中直接使用&#xff0c;供大家下载学习&#xff0c;大部分项目是基于 Android Studio开发&#xff0c;IDE为Eclipse的童鞋可通过网上教程自行转换&#xff0c;这里就不多说了。…

Android开发-创建安卓工程项目+安卓程序的运行

文章目录 前言一、为什么学习Android1.1、什么是Android1.2、Android的特点1.3、Android开发的前景 二、Android studio三、创建安卓工程项目四、第一个安卓程序的运行总结 前言 Android是基于linux平台的开源手机操作系统&#xff0c;该平台由操作系统&#xff0c;中间件&…

1、创建第一个Android项目

1.1、创建Android工程项目&#xff1a; 双击打开Android Studio。 在菜单栏File中new-->new project 3、在界面中选择Empty Activity&#xff0c;然后选择next 4、在下面界面中修改工程名称&#xff0c;工程保存路径选择java语言&#xff0c;然后点击finish Android studio自…

Android 如何创建项目

目录 一、创建流程二、Android Studio 主窗口三、链接 一、创建流程 1、安装最新版 Android Studio。 2、第一次打开Android Studio会弹出Welcome to Android Studio 窗口&#xff0c;在窗口中&#xff0c;点击 Create New Project。 如果您已打开一个项目&#xff0c;请依次…

Android开发-Android项目结构

文章目录 前言一、Gradle1.1什么是Gradle&#xff1f;1.2Gradle是一个构建工具&#xff0c;那么为什么要用构建工具&#xff1f; 二、项目结构三、app目录结构四、res目录结构总结 前言 Android工程的项目结构比较复杂&#xff0c;在进行Android开发前必须对Android项目的工程…

如何创建安卓项目

1、新建项目 2、选择一个展示页&#xff08;可以改&#xff09; 3、基本配置 Name&#xff1a;项目名 Package name&#xff1a;包名&#xff0c;自动生成&#xff0c;也可以改 Sava location&#xff1a;项目保存位置 Language&#xff1a;语言&#xff0c;Java或Kotlin…

创建Android工程项目

#找到我们安装的Android Studio&#xff0c;然后打开他 点击新建 接下来&#xff0c;咋们选择一个啥都没有的页面&#xff0c;然后继续 然后就是项目的名字路径&#xff0c;根据自己的来选择修改&#xff0c;然后点击Final创建这个项目 首次创建可能比较慢&#xff0c;需要有耐…

Android 开源项目和文章集合(更新:2022.03.21)

我做了一个思维导图&#xff0c;专门总结我学的博客文章&#xff1a;https://mubu.com/doc/j6EJGn9kZT 2023.3.20 anr系列 https://mp.weixin.qq.com/s?__bizMzI1MzYzMjE0MQ&mid2247488182&idx1&sn6337f1b51d487057b162064c3e24c439&chksme9d0d954dea750421…

Android入门(建立项目与项目结构简要介绍)

内容概要&#xff1a; 1 如何建立项目附带简要介绍 2 对项目结构进行简要介绍 1.如何建立Android项目 &#xff08;1&#xff09;进入Android studio “ File ->New-> New Project ” 新建项目 …

android项目大全,总有你所需的

版权声明&#xff1a;本文为转载&#xff1a;http://blog.csdn.net/tiantian1980/article/details/18838129 目录(?)[] 注&#xff1a;打开请贴网址&#xff0c;有些直接通过链接打开的不正确。 1.相对布局实例 http://kukuqiu.iteye.com/blog/1018396 2. Log图文详解(Log.v,L…

Android 开发一定要看的15个实战项目

前言: 虽说网上有太多的Android课程,但是大多都是视频,有Android在线开发环境的几乎没有,但是对于学习Android的人来说拥有在线的Android开发环境是非常好的,可以随时动手操作学习Android开发,及时了解自己的掌握情况! 实验楼就提供了Android在线开发环境,你不需要本…

Android项目(完整版+免费版)

Android项目–关于星座相关的app 第一部分–界面效果图 页面一&#xff1a;&#xff08;点击页面任意一个星座图标会显示相应的数据&#xff09; 页面二&#xff1a;&#xff08;可以更换男生或女生的星座&#xff0c;点击开始配对分析&#xff0c;能跳转相应的页面&#xff…

某程序员面试支付宝P7,面试已通过,却因为背调没过!再进阿里失败!阿里背调,到底调啥?...

热文推荐&#xff1a; 尘埃落定&#xff01;清华才子王垠加入华为职级22&#xff0c;前阿里P10赵海平加入字节跳动&#xff0c;职级或为4百度网盘“破解版”&#xff0c;Pandownload开发者被抓我去&#xff01;微信竟然可以查出行轨迹了&#xff0c;预计又一波情侣要分手&#…

清华人工智能研究院成立,张钹姚期智分别任院长和主任

&#xfeff;&#xfeff; 清华大学人工智能研究院成立了&#xff01; 今日&#xff0c;清华大学人工智能研究院成立仪式暨清华-谷歌 AI 学术研讨会在清华举行。据介绍&#xff0c;张钹院士将担任院长&#xff0c;图灵奖得主姚期智院士任学术委员会主任&#xff0c;同时&#x…