背景
本人目前有6年多的前端经验及1年nodejs后端经验,对于Java和Android没任何的经验。2023年初由于一些原因,前公司干不下去了,然后就和一个朋友一起搞了个小项目,项目前端需要使用原生Android进行开发,原有的项目是使用uni-app开发的,算是用Android进行重构。Android重构的工作已经进行了一部分,我算是中间接手,继续开发。后续又开发了两个新的Android应用。最初开发的时候是以前端开发的经验去类比,然后推断一些问题的处理方向。感觉都是前端开发,有很多地方是相通的,这里是是个人的一些经验总结。
示例项目参考
最初拿到项目就直接模仿着添加/修改页面了,后边一些新的项目是基于一些成熟的模板进行开发的,这里推荐一下AndroidProject这个项目,对于初学者还是比较友好的,可以快速的对Android开有一个基础的了解。
Android开发有一些专门的工具,这里推荐使用Android Studio,官网可以直接下载安装。
可以先clone下来看一下项目结构。
/Users/qiuwww/code/wide/Android-demo/AndroidProject
├── HelpDoc.md
├── LICENSE
├── README.md
├── libs # 这里是当前项目的一些内部sdk
├── app
| ├── AppSignature.jks # jsk扩展文件,签名文件
| ├── AppSignature.jpg
| ├── build.gradle # app模块的gradle构建脚本
| ├── gradle.properties
| ├── proguard-app.pro # 代码混淆配置文件
| ├── proguard-sdk.pro # 代码混淆配置文件
| └── src # 源文件目录,大部分修改的文件的位置
└── main
├── assets # 通常App内嵌的html就放在这里
├── AndroidManifest.xml # 文件定义了包名、活动、启动的活动等,整个项目的配置文件,四大组件都需要在这里注册才能正常的运行
├── java
└── com.hjq.demo # 核心的控制器文件
├── action
├── aop
├── app
├── http
├── api
├── glide
└── model
├── manager
├── other
├── ui
├── activity
├── adapter
├── dialog
├── fragment
└── popup
├── widget
└── wxapi
└── res # 存放我们各种资源文件的地方,有图片,字符串,动画,音频等,还有各种形式的XML文件
├── anim
├── drawable # 存放各种位图文件,(.png,.jpg,.9png,.gif等)除此之外可能是一些其他的drawable类型的XML文件
├── drawable-xxhdpi # 超超高分辨率,这个在高端机上有所体现
├── layout # 该目录下存放的就是我们的布局文件,另外在一些特定的机型上,我们做屏幕适配,比如480*320这样的手机,我们会另外创建一套布局,就行:layout-480x320这样的文件夹!
├── mipmap-xhdpi
├── mipmap-xxhdpi
├── mipmap-xxxhdpi
├── raw
├── values
├── attrs.xml # 自定义控件时用的较多,自定义控件的属性!
├── colors.xml # 定义颜色资源
├── dimens.xml
├── integers.xml
├── strings.xml # 定义字符串资源
└── styles.xml
└── xml
├── build # 构建时生成文件的地方
| ├── app
| └── library # 存放第三方的jar包
├── build.gradle
├── common.gradle
├── configs.gradle
├── gradle
| └── wrapper
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library
| ├── base
| ├── copy
| ├── umeng
| └── widget
├── local.properties # Android SDK NDK 环境路径配置
├── maven.gradle
├── picture
| ├── activity
| ├── demo_code.png
| ├── dialog
| ├── gif
| ├── help
| └── resource
└── settings.gradle # 这个文件用于指定项目中所有引入的模块
项目运行
- 打开Android Studio,打开项目,第一次打开项目的时候会默认去下载项目依赖,很多时候会下载不成功;
- 依赖下载不成功的情况需要设置代理,参考设置 Android Studio 代理,网速可以的话,还是比较快的;
- 配置好代理后可以重新打开项目,或者点击右上角的大象加箭头的图标(Sync Project with Gradle Files);
- 依赖下载不成功的情况需要设置代理,参考设置 Android Studio 代理,网速可以的话,还是比较快的;
- 真机模式下运行,需要有Android手机连接,这里以Mac为例(当然也可以选择使用模拟器的模式);
- 开启手机调试模式,开启USB调试;
- 数据线连接电脑和手机,通常会有一些问题,可以下载一个Android文件传输,选择传输文件模式;
- 安装完成依赖,选择运行到真机,然后点击绿色三角形(Run ‘app’),运行运行到真机,中间选择安装,等待安装;
- 安装成功就可以看到效果了,可以选择修改项目的某些内容,查看真机的效果;
如下结合这个项目及本人的前端方面的工作经验,对这两者进行一些介绍。
基础的环境配置
- Android Studio专门的开发工具,具有各种提示,速度也比较快,各种内置工具,很方便;
- Android打包发布,相对于前端代码,需要一个专门的证书,不过开发工具也可以直接生成,区别不太大;
- 配置参数相对更对,版本控制上架要求也更规范,但不会有前端的浏览器各种缓存问题;
- 开发过程:
- 页面的开发,不部分情况下可以在开发工具内直接看到展示的效果,不需要重新运行;
- 逻辑的开发,就需要真机运行后才能看到效果。不过强类型语言,很多小问题开发的时候都会提示到,所以也是很方便的;
- 每次进行编译安装,这块相对于前端开发繁琐很多,如果设备老旧可能每次都需要很久,也是很让人崩溃的。
Android的发布相对于前端更加繁琐
- 需要先申请如软著才能上架应用市场;
- 通常还需要上架多个平台如小米、华为、oppo、vivo这些平台,可能有时候有一个小问题就需要全部流程走一遍,所以开发的阶段一定要做好测试;
- 线上问题的紧急处理也要有前期的预案,不像前端一样,直接发版本覆盖就可以了。android的版本更新维护是一个长期的过程,不可能保证所有的用户都会及时的去更新最新的版本。
Android打包需要证书,证书的生成和配置如下
- 可以参考官方文档Android Studio为应用签名,
Build > Generate Signed Bundle/APK > Create new > ...
; - 证书可以选择配置在
app/src/build.gradle
中,也可以选择在打包的时候再选择证书; - 配置证书是为了后续上架使用,开发过程不受影响。
从页面开发的角度看
- Android使用xml来描述页面基础信息,与html很类似,都是尖括号标签、可嵌套、可在标签内设置相关属性等;
- Android的页面统一存放在
AndroidProject/app/src/main/res/layout
下边,各种类型扁平存放,当然你可以对他们进行分组;- 页面描述文件,通常可以设置
tools:context=".ui.activity.CrashActivity"
属性来说明对应的控制器文件,可以很方便的进行跳转;- 当然在控制器内,找到如
R.layout.crash_activity;
,也可以很方便的打开xml文件;
- 当然在控制器内,找到如
- layout下的文件的主要包括这几种类型:
- activity,通常用来描述页面;
- fragment,通常描述一个块,如一个列表,一个公共的头部等;
- item,通常描述一个列表的模板;
- dialog,描述一个对话弹框;
- widget:应用微件是可以嵌入其他应用(如主屏幕)并接收定期更新的微型应用视图;
LayoutInflater.from(getContext()).inflate
,通常使用inflate方法,作用是将一个 xml 布局文件变成一个 view 对象。
- 页面描述文件,通常可以设置
- 通常每个xml都有对应的控制器类进行操作,不像很多时候前端的页面直接所有的内容(css、html、js)都会写在一起;
- 页面的样式控制,后边会详细说明一些常用的控制属性;
- 大多时候采用的都是直接写在标签内,如
<View android:layout_width="match_parent" android:layout_height="@dimen/line_size" android:background="#ececec" />
; - 上边的这种形式不方便样式共享,当然可以借助style属性,如
style="@style/HorizontalLineStyle"
,style="@style/ButtonStyle"
,去使用前端class复用的方式去写样式。
- 大多时候采用的都是直接写在标签内,如
Android的标签
常用的html标签及对应的Android标签
- html网页文件基本结构:
<!DOCTYPE html> 、html、body、script、link、title、meta
;- 这里的标签多对应到
AndroidManifest.xml
文件内,可以理解为前端的单页面应用的index.html;<!DOCTYPE html>
=><?xml version="1.0" encoding="utf-8"?>
;html
=>activity
,对应每个页面声明和- 这里的
<activity>
,对应到每个页面,name属性对应title; - 这里的activity入口页面会添加
<intent-filter><action android:name="android.intent.action.MAIN" /></intent-filter>
声明;
- 这里的
- Android的
<application
,公共配置整体页面的一些信息,比如icon、theme、name等; - 同样的有
<meta>
标签来说明一些配置信息;
- 通常Android不会引用一些外部的脚本、组件之类的,所以不会有类似script、link的一些功能;
- 这里的标签多对应到
- html布局标签:
div、section、header、footer
;div、section、header、footer
=>View
,单纯的标签;div、section、header、footer
=>ConstraintLayout、LinearLayout、RelativeLayout
,更多的布局还是使用的这些布局标签;LinearLayout
线性布局,对应的是相对布局,这里通过orientation="vertical|horizontal"
;RelativeLayout
,相对布局,类似于html的position: absolute
;
- html表单标签:
input、radio、checkbox、select-option、form、textarea、button
;button
=> Android中的<Button>
用法区别不大,都是用来展示一个按钮;select
=> Android中的spinner
;android:entries
指明此选择器的数据源;
input
=>EditText
;- 不可输入的弹框:
android:focusable="false"
,设置不可以获取焦点,editText.setFocusable(false)
;
- 不可输入的弹框:
radio
=>RadioButton
;checkbox
=><CheckBox
;textarea
=>EditText
,这里通过设置minLines这些参数模拟出来;form
=> Android里边没有对应的标签,也不太需要;
- html展示标签:
p、span、h1-h6、br、b、i、label、img、table
;span、p
=>TextView
;img
=> 因为样式会对应多种标签,<com.android.library.YLCircleImageView、<ImageView
;
- html导航标签:
a
;- Android中只能是去
new Intent()
,然后去执行跳转,没有类似a标签的功能标签;
- Android中只能是去
- html语意化标签:
hgroup、figure、dl-dd、strong、ol-li、ul-li
;- 这里的
list
,操作起来相对复杂,不像html直接ol、ul,或者使用div模拟;
- 这里的
- html框架标签:
iframe
;<iframe>
对应Android的<WebView>
,功能都是嵌入一个网页;
- Android明确的头部导航条,前端这方面需要决定定位去模拟;
1.<navigation>
或者<androidx.appcompat.widget.Toolbar>
;
更多的查看main/res/layout
文件夹。
其他的一些标签
<androidx.core.widget.NestedScrollView
,用于页面滚动展示;
在Android中添加一个列表页面,这里边相对于前端麻烦很多
这里可以详细查看AndroidProject/app/src/main/java/com/hjq/demo/ui/fragment/StatusFragment.java
页面;
- 添加一个activity;
- 需要对应一个layout;
- 添加一个adapter;
- 也需要一个layout;
- 关联activity和adapter;
- 添加上拉;
- 添加下拉。
android里边的自定义标签,类似于自定义组件
用于定制一些特殊的效果,组合一些特殊的样式,例如这个项目内封装的一些组件:
- 如
<com.hjq.widget.view.ClearEditText
=>AndroidProject/library/widget/src/main/java/com/hjq/widget/view/ClearEditText.java
,单独的组件封装; - 弹框的封装,如
AndroidProject/app/src/main/java/com/hjq/demo/ui/dialog/AddressDialog.java
,里边的弹框都基于AndroidProject/app/src/main/java/com/hjq/demo/ui/dialog/CommonDialog.java
封装的。
样式控制css,以及style,class等
行内标签、盒子模型
- Android中没有行内、块级标签的概念,可以认为都是块级标签,通过
orientation
控制排列方式; - Android有类似的盒子模型的概念,有padding、margin的概念,width和height会包括padding,但是不包括margin,近似于怪异盒子模型。常用的一些属性;
- layout_marginTop;
- layout_marginLeft;
- layout_marginVertical;
- paddingTop;
- paddingHorizontal;
- 这里的border不属于布局,通常作为background来进行设置;
行内样式属性
id
,属性,与html里边的意义一样,用来获取标签,不可以重复,写法也相对固定,如android:id="@+id/ll_login_body"
;- 每个标签基础的都需要设置
layout_width
和layout_height
,然后在属性值里边控制适应性,这里不设置就会报错;- 绝对值,一般使用dp来控制;
match_parent
,适配父元素的宽高;wrap_content
,适应内部元素撑开的高度;
- 控制排布方向,
orientation
属性来控制;
使用class抽离公共的样式
- 在
main/res/values/styles.xml
里边定义; - 使用如
style="@style/HorizontalLineStyle"
;
样式的值 / 资源文件
- Android的资源文件都会被放在res下边;
- 还会允许根据不同的分辨率型号,使用不同大小的文件;
- 都会随着打包进目标文件内;
- 这里可以作为一个优化点,如本地改远端,压缩图片等;
- Android里边的外观通常使用
dp
,字体通常使用sp
; - 通常在
main/res/dimens.xml
,里边进行设置; - 通常的图片可以使用
drawable/xml
文件,或者mipmap/图片
这样来设置本地图片,也可以设置远端的图片;
理解Android中PX、DP、SP的区别
- px:其实就是像素单位,比如我们通常说的手机分辨列表800*400都是px的单位;
- sp:同dp相似,还会根据用户的字体大小偏好来缩放;
- dp:虚拟像素,在不同的像素密度的设备上会自动适配;
- dip:同dp;
- dp与sp的区别:
- 长度宽度的数值要使用dp作为单位放入
dimens.xml
文件中; - 字体大小的数值要使用sp作为单位,也放入
dimens.xml
文件中;- 使用sp作为字体大小单位,会随着系统的字体大小改变,而dp作为单位则不会;
- sp除了受屏幕密度影响外,还受到用户的字体大小影响;
- 因此通常情况下,我们还是建议使用sp作为字体的单位,除非一些特殊的情况,不想跟随系统字体变化的,可以使用dp。
- 长度宽度的数值要使用dp作为单位放入
其他的一些css效果、有style
color、text、textSize、minWidth、hint、inputType
,这些常用属性的设置都比较类似;gravity、layout_gravity
;- 当你设定一个布局
android:gravity="center"
时,它的子组件就会居中; android:layout_gravity
,用来指定当前组件(布局或View)在父组件(布局)中的位置,父布局应该是LinearLayout或者它的后裔;
- 当你设定一个布局
background
,这里的background和html里边的类似,用于设置背景,可参数可以是xml或者图片;- Android里边的
border、border-radius
只能使用background来设置;
- Android里边的
布局管理器
- LinearLayout:线性布局管理器(默认),分为水平(horizontal)和垂直(vertical)两种,只能进行单行布局;
- FrameLayout:所有组件放在左上角,一个覆盖一个;
- TableLayout:任意行和列的表格布局管理器,其中TableRow代表一行,可以向行中增加组件;
- RelativeLayout:相对布局管理器,根据最近一个组件或者顶层父组件来确定下一个组件的位置。
Android应用架构
应用框架主要说一下应用的入口,具体参考AndroidProject/app/src/main/java/com/hjq/demo/app/AppApplication.java
。
Activity
- 是一个包含应用程序的用户界面窗口。一个应用程序可以有零个或多个活动。Activity 是所有程序的根本,所有程序都运行在Activity之中,Activity具有自己的生命周期,由系统控制生命周期,程序无法改变;
- 可以理解为一个
new Vue()
,或者一个React.component()
;
Android的核心类
一些 Android 开发者可用的 Android 核心程序库总结如下:
- android.app – 提供应用程序模型的访问,是所有 Android 应用程序的基石。
- android.content – 方便应用程序之间,应用程序组件之间的内容访问,发布,消息传递。
- android.database – 用于访问内容提供者发布的数据,包含 SQLite 数据库管理类。
- android.opengl – OpenGL ES 3D 图片渲染 API 的 Java 接口。
- android.os – 提供应用程序访问标注操作系统服务的能力,包括消息,系统服务和进程间通信。
- android.text – 在设备显示上渲染和操作文本。
- android.view – 应用程序用户界面的基础构建块。
- android.widget – 丰富的预置用户界面组件集合,包括按钮,标签,列表,布局管理,单选按钮等。
- android.webkit – 一系列类的集合,允许为应用程序提供内建的 Web 浏览能力。
四大类
- Activities:描述UI,并且处理用户与机器屏幕的交互;
- 一个活动标识一个具有用户界面的单一屏幕;
- Services:处理与应用程序关联的后台操作;
- 服务是运行在后台,执行长时间操作的组件;
- Broadcast Receivers:处理Android操作系统和应用程序之间的通信;
- 广播接收器简单地响应从其他应用程序或者系统发来的广播消息;
- 广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用 Context.sendBroadCast()、Context.sendOrderedBroadcast()、 Context.sendStickyBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收(就像真的收音机一样);
- Content Providers:处理数据和数据库管理方面的问题;
- 内容提供者组件通过请求从一个应用程序到另一个应用程序提供数据。
应用的生命周期
具体参考,通常情况使用模板开发不太会去修改;
- onCreate 只会被调用一次
- 当app切换到后台时会调用onPause,onStop
- 当app切换回前台时会调用onStart,onResume
- onDestroy 不会被调用
本地存储
- SharedPreferences:用户偏好设置;
MyApplication.getInstance().getSharedPreferences(
,查看具体使用;
- 内部存储,数据存储到手机内置存储器;
- 外部存储,外部SD卡中存储数据;
- SqlLite本地数据库存储;
- ContentProvider;
通常情况下,使用类似localStorage功能的是SharedPreferences
方式,方便存储一些token之类的参数,对于数据结构比较复杂的情况可能会使用到SqlLite这种小型的数据库来操作,图片之类的资源会被保存在外部存储器。
build.grade的配置
一些常见的配置项。
- defaultConfig,一般的信息配置;
- signingConfigs配置签名;
- buildTypes,打包版本的信息配置,当前项目就对不同的版本设置了不同的应用名称;
applicationVariants.all
,设置打包名称的组合;dependencies
,依赖的一些外部包;
AndroidManifest.xml
- 这个文件日常开发的时候通常会去修改或者添加删除路由,每一个
<activity>
对应一个可以挑战的页面; manifest.package
,这里设置包名,相同的包名被认为是同一个应用;<uses-permission
,通常用来做权限声明,对于需要的权限,需要在这里声明,有一些还要在使用的时候去拉起使用的弹框,比如选择图片、保存图片这些;
拿到一个项目,最基础开发,添加页面跳转
页面通常存放在AndroidProject/app/src/main/java/com/hjq/demo/ui/activity
目录下边,可以查找类似的页面进行修改。
页面的生命周期
具体参考了解 Activity 生命周期,但是常用的声明周期只是简单的几个:
- onCreate;
- onDestroy;
- finish;
- onResume,页面更新和初始化的时候,会被执行。这是应用与用户互动的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用;
在当前项目模板下,被封装为如下的两个,详细查看Android-demo/AndroidProject/app/src/main/java/com/hjq/demo/app/AppActivity.java
:
initView
,通常用于初始化页面模板,获取操作dom的节点;initData
,通常用于获取数据之类的操作;
上边的两个执行时机,紧挨着,本质上区别不大,都是在onCreate阶段执行;
添加一个页面
- copy一个activity;
- copy一个layout;
- 关联上边的两部分,
setContentView(R.layout.address_dialog);
- 在
AndroidManifest.xml
添加路由。
路由系统/页面跳转
- Android中的跳转,都是一种“意图Intent”;
- 调用startActivity|startActivityForResult,表示打开一个新的activity;
- android的跳抓是基于堆栈的,不能直接redirect;
- finish方法是可以删掉当前页面的堆栈的;
- 所以跳转前finish就可以实现redirect了;
- 回退操作,只能是回退一个页面,不能跳转页面回退,这样需要直接startActivity。
// 直接跳转
Intent intent = new Intent(this, VerifyMnemonicBackupActivity.class);
// 拼接参数
intent.putExtra("walletId", walletId);
intent.putExtra("walletMnemonic", walletMnemonic);
// 如果需要类似redirect的操作,就在跳转前finish
finish();
startActivity(intent, VERIFY_MNEMONIC_BACKUP_REQUEST);
// 实际操作中都会进行封装
事件
- 获取节点;
- 设置点击事件;
// 1. 声明dom节点变量
private ImageView iv_imgCode;
// 2. 绑定事件
@Override
protected void initView() {
iv_imgCode.setOnClickListener(this);
}
@SingleClick
@Override
public void onClick(View view) {
if(view == iv_imgCode) {
getCaptchaHandler();
}
}
这里的操作比较类似使用js直接写页面,事件比较多的时候写起来很费劲,也有方便的操作方式。
接口请求
参考AndroidProject/app/src/main/java/com/hjq/demo/http
,本质上与前端调用接口没什么区别,只是使用的工具不同,这里定义的参数更多。
Android里边的接口请求依赖Activity的上下文环境,不能单独的在一个文件内调用接口。
Java基础语法
主要介绍一些常用到的语法
这里只说一些常用的,本人自己用到的一些,更多的可以自行学习,这方面我也是个菜鸟。
- 字符串与数值的转换,Java的类型非常多;
int i = Integer.parseInt(s);
;String s = String.valueOf(value);
;
- 空值的判断;
- null的判断;
if(user == null)
;
- “”的判断;
str.isEquals("")
;TextUtils.isEmpty(Id)
;
- null的判断;
- 类型的定义;
private static final String INTENT_KEY_IN_CODE = "code";
;private int status = 0;
;String[] array = {"a","b","c","c","d","e","e","e","a"};
;private Button btnSubmit, showModalBtn;
;private String nickname;
;- …
- TimeUnit是java.util.concurrent包下面的一个类,表示给定单元粒度的时间段;
- 当整数直接量赋给long、float或者double,而不添加尾缀,虚拟机也会直接将int类型数据自动转换为对应类型然后赋值。因为数据长度短的转换为长的并不会造成数据丢失,所以默认可以自动转换;
- 当浮点直接量(例如:1.2等),JVM虚拟机默认为double类型,如果直接赋值给float就会引起编译器报错。
Java修饰符
@Deprecated
:Java 中 @Deprecated 可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告;- 缺少闭包(closure):闭包的缺失使得 Java 中函数式编程支持较差;
protected abstract void initData()
,抽象化的组件需要去实现才有用,才能算是有这个方法;- abstract:由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用;
protected void initSoftKeyboard() {
;- 被 protected 修饰的成员对于本包和其子类可见;
- 基类的 protected 成员是包内可见的,并且对子类可见;
- 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法;
- 被 protected 修饰的成员对于本包和其子类可见;
private
: 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
Java对比JS
- JavaScript的异步与Java同步带来的一些差别;
- Android主要就是主进程(ui进程),需要请求数据的时候就会开启子线程去处理,包括一些定时任务等;
- js没明显的区分,遇到异步,会自动开启子线程处理;
- 只能在UI线程操作UI视图,不能在子线程中操作。
装饰器
- @Override;
- 重写(Override)与重载(Overload);
- @SingleClick;
- @NonNull;
- …
Builder
- 它其实是一种设计模式,叫做建造者模式,它的含义是将一个复杂的对象的构建与它的表示分离,同样的构建过程可以创建不同的表示;
- 当我们需要创建一个复杂的对象时,使用静态工厂或者构造器的方式就显得特别笨拙和丑陋,因为它们有个共同的局限性:它们都不能很好地扩展到大量的可选参数,也就是说,灵活性很差;
- 也就是对于多个参数,需要添加很多类型的构造函数,还不一定都能覆盖得到(重叠构造器模式);
- 使用JavaBeans模式创建复杂对象;
- 类似给控对象上逐步的添加属性和方法;
- builder模式,实际上类似于将构造函数拆分的操作;
- 该模式的内涵是:不直接生成想要的对象,而是让客户端利用所有必要的参数构造一个Builder对象,然后在此基础上,调用类似于Setter的方法来设置每个可选参数,最后通过调用无参的build()方法来生成不可变对象。一般地,所属Builder是它所构建类的静态成员类。
Android的同步和异步操作
- Thead;
- AsyncTask;
- IntentService;
- 线程池。
总结
- Android于前端开发的核心思想没什么改变;
- Android 方面则是 MVP 架构,其主要依赖于约定俗成;
- android体系庞大,这里只是从目前一段时间的学习开发经历,介绍了一些常用到的功能;
- android写列表太麻烦了,相对于前端一个循环直接输出标签来说,Android每次都需要复制修改三四个文件来创建一个列表,麻烦太多了;
- Java强类型语言比js以及TS都好用很多;
- Android上架挺折腾的。
参考文章
- 面向开发者的Android;
- EditText(输入框)详解;
- Application的应用和生命周期;
- Android本地数据存储方案(一);
- android和前端开发的区别;
- 一个前端程序员的一个月原生 Android 开发体验;
- 客户端转 Web 前端后,这半年我的一些思考;
- Android的XML常用标签整理;
- Android Studio工程目录结构及简单使用;
- Android异步任务实现详解;
- 两分钟理解Android中PX、DP、SP的区别;
- 优雅地创建复杂对象 —— Builder 模式;
后续会持续更新。以上只是个人见解,请指教,个人blog。