赞
踩
由上图可知,安卓系统可以分为6部分:
Android系统在2008年发布了1.0,5.0将Dalvik虚拟机替换成了ART虚拟机,6.0加入了运行时权限
安卓版本 | 发布时间 | 版本号 |
---|---|---|
Cupcake | 2009年4月 | 1.5 |
Donut | 2009年9月 | 1.6 |
Eclair | 2009年10月 | 2.0-2.1 |
Froyo | 2010年5月 | 2.2-2.2.3 |
Gingerbread | 2010年12月 | 2.3-2.3.7 |
Honeycomb | 2011年2月 | 3.0-3.2.6 |
Ice Cream Sandwich | 2011年10月 | 4.0-4.0.4 |
Jelly Bean | 2012年7月 | 4.1-4.3.1 |
KitKat | 2013年10月 | 4.4-4.4.4 |
Lollipop | 2014年11月 | 5.0-5.1.1 |
Marshmallow | 2015年10月 | 6.0-6.0.1 |
Nougat | 2016年8月 | 7.0-7.1.2 |
Oreo | 2017年8月 | 8.0-8.1 |
Pie | 2018年8月 | 9 |
Android 10 | 2019年9月 | 10 |
Android 11 | 2020年9月 | 11 |
Android 12 | 2021年10月 | 12 |
gradle更新太快了,书上的命令执行不成功,看一看就行了
学习本书需要安卓基础
需要的工具:
下载AS默认安装即可
打开AS之后,点击新建项目
选择一个空Activity
填写项目配置:
点击finish就可完成项目的插件
第一个创建项目之后,发现gradle同步失败,报错:
Plugin [id: 'com.android.application', version: '7.4.2', apply: false] was not found
后来google发现是代理的问题,关掉代理即可,但是as设置代理有三个的覅发
第一处
第二处
在这个文件中把代理相关的设置去掉
第三处
删除以下文件
C:\Users\admin\.gradle
即可
点击右上角小手机
点击Create Device
选择phone->n5x
系统选择安卓8,第一次需要下载一下
给手机起个名字,点击finish就创建完成
在Deveice Manager就可以看到各个创建出来的手机
锤子图标构建项目,运行图标运行项目,构建前选一下项目,运行前选一下手机
成功运行:
monitor用于监视Android设备的允许,位于 \AndroidSDK\tools
下,点击monitor.bat
即可启动
ADB:Android Debug Bridge,也是专门用于调试安卓设备的工具,有很多功能,位于Android SDK安装目录下的platform-tools文件夹下。
ADB的功能如下:
adb devices
PC->手机
adb push test.txt /sdcard/test.txt
手机->PC
adb pull /sdcard/test.txt a.txt
adb shell
安装:
adb install [-r] [-s] <file>
卸载:
adb uninstall [-k] <package>
mksdcard是一个创建虚拟存储卡的工具,位于Android SDK下的emulator目录下,使用如下命令可创建一个虚拟存储卡
mksdcard.exe 64M test.img
如果希望启动模拟器时使用指定的虚拟SD卡,可以使用如下命令:
emulator -avd 模拟器名字 -sdcard test.img
开发Android应用三步骤:
创建一个Android应用程序之后,在\app\src\main\res\layout
目录下存在一个xml文件,这个xml文件就是用来定义用户界面的。
下面添加一个Button到界面上,然后给Button添加一个text,定义一个点击响应方法,其中id就是这个按钮的标识
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="clickHandler" //定义消息响应函数 android:text="点击我" //定义按钮文本 app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
这里的消息响应函数写的是字符串,可见IDE会通过反射去调用这个clickHandler方法,那这个方法又在哪个类中呢?
每个xml即用户界面都对应一个Activity类,这个类就负责这个界面的消息响应,比如刚刚创建的项目,就只有一个activity_main.xml和一个MainActivity类,这两者就是相对应的,所以需要在MainActivity编写按钮的响应方法clickHandler
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n5CbInqO-1681241138979)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681220994702-a2651a69-d0bf-49ec-affc-e2edd14b2148.png#averageHue=%23f9f8f7&clientId=u43465e45-6ba4-4&from=paste&height=629&id=u1f7c189b&name=image.png&originHeight=943&originWidth=2064&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=152679&status=done&style=none&taskId=u0ba3850d-28c1-4d4d-aa34-5d6cfadd202&title=&width=1376)]
在clickHandler方法中,传入了一个View对象,这个对象应该就是Button类的对象,View类应该是Button类的父类,所以这里可以直接将View类转成TextView类或者Button类,然后设置文本,也可以调用findViewById
方法通过资源ID来获取Button对象。
public void clickHandler(View source){
//TextView tv = findViewById(R.id.button);
//tv.setText("Hello Android-" + new java.util.Date());
Button btn = (Button)source;
btn.setText("Hello Android-" + new java.util.Date());
}
TextView类是Button类的父类,所以用TextView来设置和Button来设置都可以
如果只是单纯的开发Android应用程序,只需要编写xml定义界面,编写Activity类编写业务代码即可,但是项目中其他的这么多文件是用来干什么的呢?我们来分析一下。
整个项目结构如下:
其中关键的是app文件夹,代表了一个app模块,这也是我们刚刚创建的安卓项目的唯一的一个模块,我们了解这个文件夹里面的内容即可,而其他的文件和目录则是gradle和idea的一些全局配置。
来看app模块的结构
可见这是一个Gradle项目,下面是build.gradle的解释
plugins { // 应用com.android.application插件,该插件提供了构建Android应用程序所需的任务和默认配置 id 'com.android.application' } //构建Android应用程序时的配置和选项 android { // 应用程序的命名空间 namespace 'com.example.hello' // 应用程序编译所需的SDK版本 compileSdk 33 defaultConfig { // 应用程序包名 applicationId "com.example.hello" // 应用程序的最小SDK版本 minSdk 26 // 应用程序的目标SDK版本 targetSdk 33 // 应用程序版本号 versionCode 1 // 应用程序版本名称 versionName "1.0" // 测试运行器 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { // 是否启用混淆 minifyEnabled false // 混淆规则 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { // 源代码兼容性版本 sourceCompatibility JavaVersion.VERSION_1_8 // 目标代码兼容性版本 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { // 应用程序依赖项,可以替换成国内的仓库 implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' }
src是源码文件加,其下有三个文件夹:
我们需要关注的是main目录:
以前是R.java文件,现在被替换成了R.txt和R.jar,在R.txt中有所有的资源ID字符串和ID值的对应关系
比如我们刚刚创建的Button,id给的是button_test,id值就是0x7f080063,所以这个ID其实被编译成了R类的子类int类的一个静态常量,所以在Java代码中访问是 R.id.button_test,在编译时就会被替换成0x7f080063
res目录下存储了app的所有资源,包括图片、字符串、颜色、尺寸等。不同的资源放在不同的文件夹内,方便让AAPT工具来扫描,生成对应的R.txt文件和R.jar文件。
以字符串为例,字符串资源存放在string.xml中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkGFulDC-1681241138980)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681224981971-32e3401d-10c7-47f4-959c-e2394a4d8e8d.png#averageHue=%23f9f8f7&clientId=u43465e45-6ba4-4&from=paste&height=623&id=u5c2918b5&name=image.png&originHeight=934&originWidth=2044&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=89706&status=done&style=none&taskId=u27a4bb8b-2fa0-43d8-bbfa-0c9781cebe1&title=&width=1362.6666666666667)]
文件中定义了一个字符串常量,名字是app_name,值是"Hello",定义好之后,就可以在Java代码,XML文件中使用这个字符串资源。
AAPT工具为每一种资源创建了一个内部类,这些内部类都在R类中,所以访问上述的字符串资源可以通过R.String.app_name
来访问
btn.setText(String.format("%x: %s", R.string.app_name, new java.util.Date()));
在xml中使用资源的格式:
@内部类名/资源名
比如在Button资源的定义中,使用字符串
android:text="@string/app_name"
分配资源标识符:
android:id="@+id/button_test"
要引用这个id标识符,也是通过下面这种方式访问
@id/button_test
清单文件通常包含以下内容:
下面是刚刚创建的Android程序的manifest文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.Hello" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
我们来逐行解释一下:
第一行是xml文件的声明,使用的xml版本是1.0,编码是utf8
<?xml version="1.0" encoding="utf-8"?>
然后是定义了一个根元素manifest,同时指定了两个命名空间android和tools,其中android命名空间是用来指定Android操作系统使用的属性或者元素,比如android:icon="@mipmap/ic_launcher"
指定了应用程序的图标,这个图标会被系统所用来展示app,而tools用来指定在构建app是用到的属性或者元素,比如 tools:targetApi="31"
指定了静态分析工具所使用的目标API版本。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
接下来定义了一个application元素,这代表一个应用程序,里面包含一些应用程序级别的属性和配置,包括:
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Hello"
tools:targetApi="31">
最后,定义了一个activity元素,代表一个Activity组件,其中包含了Activity的名称.MainActivity
,是否允许被调用android:exported
在activity中,定义了一个intent-filter元素,这个元素的内容指定了此activity能够处理的Intent种类。
在intent-filter元素中,action标签用于声明能够处理的Intent操作类型,category用于声明能够处理的Intent的种类。
MAIN表示这个组件是应用程序的入口点,LAUNCHER表示这个组件可以被应用程序的启动器调用,总而言之就是这个Activiy是app启动的第一个Activity
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
app需要一些权限才能使用系统的功能,所以需要在manifest文件中声明自己所需要的权限。
在元素内添加子元素即可声明权限,比如
<uses-permission-sdk-23 android:name="android.permission.CALL_PHONE"></uses-permission-sdk-23>
在Android6之前,权限声明是<uses-permission>
,并且在安装APP时需要用户同意申请的全部权限。
在Android6以后,Android系统加入了动态权限申请机制,声明权限变成了<uses-permission-sdk-23>
,除了这个声明,还需要写代码动态申请权限,上面的声明只是告诉系统需要使用这些权限,但并不会在安装时提示用户授权,在运行时执行到申请权限的代码时才会提示,所以,在高版本系统中,申请权限需要两个动作:1. 在清单文件中加上权限声明;2. 写代码动态申请权限。
系统中常用的权限如下:
权限关键字 | 说明 |
---|---|
android.permission.CAMERA | 允许应用访问摄像头进行拍照和视频录制 |
android.permission.RECORD_AUDIO | 允许应用录制音频 |
android.permission.READ_CONTACTS | 允许应用读取用户的联系人信息 |
android.permission.WRITE_CONTACTS | 允许应用修改或删除用户的联系人信息 |
android.permission.CALL_PHONE | 允许应用拨打电话 |
android.permission.READ_PHONE_STATE | 允许应用读取设备的电话状态 |
android.permission.READ_SMS | 允许应用读取短信 |
android.permission.SEND_SMS | 允许应用发送短信 |
android.permission.READ_CALENDAR | 允许应用读取用户的日历信息 |
android.permission.WRITE_CALENDAR | 允许应用修改或删除用户的日历信息 |
android.permission.ACCESS_FINE_LOCATION | 允许应用访问设备的精准位置信息 |
android.permission.ACCESS_COARSE_LOCATION | 允许应用访问设备的大概位置信息 |
android.permission.WRITE_EXTERNAL_STORAGE | 允许应用写入外部存储(例如SD卡) |
android.permission.READ_EXTERNAL_STORAGE | 允许应用读取外部存储(例如SD卡) |
android.permission.INTERNET | 允许应用访问网络 |
安卓App通常由一个或者多个基本组件组成,最重要的就是四大组件:
Activity是安卓系统中负责与用户进行交互的组件,但它本身不显示内容,要显示内容需要借助View类,通过setContentView来显示View类。
View组件是所有UI控件、容器控件的基类,View组件就是安卓App中用户实实在在能看到的部分,但是VIew组件需要放到容器中或者通过Acticity显示出来。
实际上,Activity就是窗口的容器,其包含一个getWindow方法来获取Window对象,这个方法返回一个Windows对象,那么一个Activity对应一个Window对象?如果不调用setContentView来显示View,则该Activity显示一个空窗口。
Activity包含一个setTheme方法来设置窗口风格。
一个安卓App可以包含多个Activity,多个Activity形成Activity栈,当前活动的Activity位于栈顶。
Service也是一个单独的Android组件,通常位于后台运行,没有界面,拥有自己独立的声明周期,通常用于为其他组件提供后台服务,或者监控其他组件的运行状态。
BroadRecevier是广播接收者,用于监听安卓App中其他组件的消息,其他组件可以通过sendBroadcast来触发注册了BroadRecevier的onReceive方法。
注册广播接收者有两种方式:
ContentProvider是内容提供者,通常用于跨进程共享数据,一个应用通过ContentProvider提供数据,另一个通过ContentResolver来访问数据。
Intent不是组件,但是是安卓应用程序内不同组件之间通信的载体,当App运行时需要连接不同组件时,就需要借助Intent来实现。
比如:
都需要借助Intent,Intent封装了目标组件的信息。
Intent分类:
系统如何判断组件是否满足隐式Intent要求呢?这就是通过IntentFilter来实现了,组件可以通过IntentFilter来声明自己所满足的条件。
签名的作用:
在使用AS调试程序的时候,会打一个调试签名,这样签名的App不能直接发布。
build->Generate Signed Bundle/APK
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CxikCVeM-1681241138980)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681239572706-54927b48-88d6-45cd-8cf4-57023fb67fae.png#averageHue=%23f1f0ed&clientId=u43465e45-6ba4-4&from=paste&height=379&id=u8c64f1d6&name=image.png&originHeight=569&originWidth=1089&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=80183&status=done&style=none&taskId=u9aaf7ee2-2e93-488e-aeab-bb65f25d170&title=&width=726)]
选择APK,不要选AAB
第一次用是没有key的,需要创建一个新的
填写一个表格,点击ok,就能创建成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cxquL7dD-1681241138981)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681239877441-df6c2c0f-4d08-42bf-99d8-f968bb3c364b.png#averageHue=%23f2f1f1&clientId=u43465e45-6ba4-4&from=paste&height=531&id=ua6466b0e&name=image.png&originHeight=796&originWidth=765&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=46789&status=done&style=none&taskId=u2173918b-ab00-41aa-9146-3b58301bcf7&title=&width=510)]
填写一下密钥的信息,点击next
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5KWLn1vz-1681241138981)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681239947587-d4075782-196a-4380-83b8-8b51aaaf3c27.png#averageHue=%23f1f0f0&clientId=u43465e45-6ba4-4&from=paste&height=405&id=u1bbf0333&name=image.png&originHeight=608&originWidth=774&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=37276&status=done&style=none&taskId=ufa7ef805-a211-48bc-a31d-33d0450b407&title=&width=516)]
选release,点击Create,就会开始签名
稍等也会,就会签名成功,然后会在右小角弹窗,点击locate就能定位到签名好的APK位置,在\app\release下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02DwhOoV-1681241138981)(https://cdn.nlark.com/yuque/0/2023/png/35508227/1681240024861-c8396db3-7769-4f1d-a34d-570e07999bac.png#averageHue=%23eae8e7&clientId=u43465e45-6ba4-4&from=paste&height=137&id=u493588c2&name=image.png&originHeight=206&originWidth=523&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=13427&status=done&style=none&taskId=u81167185-1d6a-42bb-9fe4-7ba23c9025d&title=&width=348.6666666666667)]
通过adb可以将apk安装到安卓手机上去
adb.exe install .\app-debug.apk
步骤:
keytool -genkeypair -alias st0ne -keyalg RSA -validity 400 -keystore st0ne.jks
,输入命令之后需要输入密码,以及信息
apksigner sign --ks st0ne.jks --ks-key-alias st0ne --out signed.apk app-debug.apk
apksigner verify -v .\signed.apk
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。