【Android】入门

Android入门:工程、打包、调试全解析

Hello World

工程结构

工程结构
之所以有这么多“mipmap”开头的目录,其实主要是为了让程序能够更好地兼容各种设备。 drawable 目录也是相同的道理,虽然 Android Studio 没有帮我们自动生成,但是我们应该自己创建 drawable-hdpi、drawable-xhdpi、drawable-xxhdpi 等目录。在制作程序的时候,最好能够给同一张图片提供几个不同分辨率的版本,分别放在这些目录下,然后程序运行的时候,会自动根据当前运行设备分辨率的高低选择加载哪个目录下的图片。当然这只是理想情况,更多的时候美工只会提供给我们一份图片,这时你把所有图片都放在 drawable-xxhdpi 目录下就好了,因为这是最主流的设备分辨率目录。

资源使用

打开 res/values/strings.xml 文件,内容如下所示:

<resources>
    <string name="app_name">HelloWorld-Java</string>
</resources>

可以看到,这里定义了一个应用程序名的字符串,我们有以下两种方式来引用它。

  • 在代码中通过 R.string.app_name 可以获得该字符串的引用。
  • 在 XML 中通过@string/app_name 可以获得该字符串的引用。

基本的语法就是上面这两种方式,其中 string 部分是可以替换的,如果是引用的图片资源就可以替换成 drawable,如果是引用的应用图标就可以替换成 mipmap,如果是引用的布局文件就可以替换成 layout,以此类推。
AndroidManifest.xml 文件:

<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:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.HelloWorldJava">

其中,HelloWorld 项目的应用图标就是通过 android:icon 属性指定的,应用的名称则是通过 android:label 属性指定的。

代码分析

  1. AndroidManifest.xml 文件,对 MainActivity 进行注册,没有在 AndroidManifest.xml 里注册的 Activity 是不能使用的。
<?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:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <activity
            android:name=".AAct"
            android:exported="false" />
            
        <!--注册MainActivity-->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <!--表示MainActivity是这个项目的主Activity,点击应用图标,首先启动的是这个Activity-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    
</manifest>
  1. MainActivity文件。MainActivity 是继承自 AppCompatActivity 的。AppCompatActivity 是 AndroidX 中提供的一种向下兼容的 Activity,可以使 Activity 在不同系统版本中的功能保持一 致性。而 Activity 类是 Android 系统提供的一个基类,我们项目中所有自定义的 Activity 都必须继承它或者它的子类才能拥有 Activity 的特性。
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        // 把布局文件activity_main放在Activity中显示
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        // 把布局文件activity_main放在Activity中显示
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }
}
  1. activity_main.xml文件。TextView是 Android 系统提供的一个控件,用于在布局中显示文字。
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

签名打包

签名打包

APK包构成

  • Dex:.class 文件处理后的产物,Android 系统的可执行文件
  • Resource:资源文件,主要包括 layout、drawable、animator,通过 R.XXX.id 引用
  • Assets:资源文件,通过 AssetManager 进行加载
  • Library:so 库存放目录
  • META-INF:APK 签名有关的信息
    APK包构成

APK包构建过程

  1. 编译:生成res 和aidl 的java类
    java类->class-> DEX 文件

  2. 链接:res 二进制资源 arsc与和R清单关联;class文件关联对应native库

  3. 打包:将 DEX 文件和二进制资源组合成 APK 或 AAB(具体取决于所选的 build 目标)。

  4. 签名:打包器使用调试或发布密钥库为 APK 或 AAB 签名。

  5. 优化:使用 zipalign 工具对apk进行优化,以减少其在设备上运行时所占用的内存
    APK包构建过程

Application

Application是用来维护全局应用状态的基类。可以创建子类并且在AndroidManifest.xml文件中通过name属性来标记Application入口类

特点

  • 单例模式:每个App都有且只有一个Application的实例对象(多进程APP除外),可以通过继承Application子类
    来进行自定义,如果没有自定义的话,APP会在打开时自动创建一个默认的实例对象。

  • 生命周期:当前进程内最长没有之一。

  • 获取方式:如果没有自定义Application的话,同样可以获取到Application对象,使用Activity.getApplication()或者Context.getApplicationContext()方法都可以获取到。

创建继承自Application类的子类

public class MyApp extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        // do something
    }
}

配置自定义 Application
在 AndroidManifest.xml 文件中声明 Application

<application
     android:name=".MyApp"            
</application>

常用方法

  • onCreate()
    在应用程序启动时,不要处理耗时任务,一般做一些三方sdk异步初始化
  • onLowMemory()
    可以在这个回调方法中做一些优化,防止被系统杀进程,目前用这个方法的情景并不多见,除非开发者想向下兼容的比较深,目前可以用onTrimMemory()替代
  • onTrimMemoey()
    这个方法目前用来替代上面的onLowMemory()方法,方法会传入一个level的int参数,这是一个目前系统通知给App的一个内存不足等级,越高越严重,不同的等级系统会对App做出不同的操作。
  • ActivityLifecycleCallbacks
    这是一个接口,可以通过registerActivityLifecycleCallbacks()和unregisterActivityLifecycleCallbacks()来注册/注销对所有Activity生命周期的监听,当Activity的生命周期发生改变的时候,就会调用接口里的方法。
  • onConfigurationChanged(Configuration newConfig)
    配置发生变化

Gradle

gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化建构工具。

所谓的构建过程就是:编译,测试,依赖管理,打包,部署。以前我们开发是手动导入 jar 包的,类似于面向过程,一步一步来,缺什么包就导什么包,很麻烦,容易出错,jar 包版本还不统一,需要关心 jar 包与 jar 包之间的依赖。通过采用 gradle 的构建方式,只需通过 complie xxxxx 引入一个 jar 包,然后这个 jar 包所依赖的其他 jar 包 gradle 会自动帮引入,无需关心 jar 包与 jar 包之间的依赖,在什么地方以什么形式引入外部 jar 包,都委托给 gradle 管理了,体现了面象对象的思想,无需关心内部实现过程,直接引入就可。(注意:Gradle 不是一种编程语言,它不能帮你实现软件中的任何实际功能)

Android studio 的默认插件是 Gradle,或许是因为 Gradle 编译速度比 Maven 快很多,而且 Gradle 完全兼容 kotlin 语言。当我们新建一个 android 项目,gradle 已经默认配置好了。

打开 gradle-wrapper.properties 文件,查看配置信息:可以看到 distributionUrl=https://services.gradle.org/distributions/gradle-5.1.1-all.zip 说明默认使用的是 gradle 5.1.1 的版本,当然可以改成我们本地有的版本,distributionUrl=file:///+gradle 的本地路径,例如:distributionUrl=file:///c:/tools/gradle-5.6.4.zip 就可以了。 android gradle 插件详解地址:https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn

build.gradle

build.gradle 文件分别在项目目录下和对应 module 目录都有存在。
下图是项目目录下的 build.gradle:
在这里插入图片描述
接下来是 module 目录的 build.gradle:

module 目录下的的 build.gradle 里的 dependencies {…}里面的依赖,是单单一个模块本身所需的依赖,是程序运行的编译依赖。
在 External Libraries 文件夹下,如图
在这里插入图片描述
可以看到项目添加的所有依赖,包括子依赖都会显示在里面。除 build.gradle 里的 dependencies {…}里面添加的依赖之外的依赖都是子依赖。
子依赖都是 gradle 智能自动的帮你添加的,它检查到你主动添加的依赖,又依赖于其他依赖,就会帮你加上。另外当 gradle 检查到依赖间有冲突时,出现依赖间多次引用相同 jar 包(只能将库里的源码打进去,而资源什么的不能打进去)、aar 包(自动的将资源文件和源码一起打进去,不用担心资源缺失的问题),它只会默认选择版本较高的添加,不会重复添加。这就是 gradle 出色的依赖管理。

Android 调试桥(Android Debug Bridge , adb)

Android 调试桥(adb)是一种功能多样的命令行工具,可让您与设备进行通信。adb 命令可用于执行各种设备操作,例如安装和调试应用。 adb 提供对 Unix shell (可用来在设备上运行各种命令)的访问权限。它是一种客户端-服务器程序,包括以下三个组件:

  • 客户端:用于发送命令。客户端在开发机器上运行。您可以通过发出 adb 命令从命令行终端调用客户端。
  • 守护程序(adbd):用于在设备上运行命令。守护程序在每个设备上作为后台进程运行。
  • 服务器:用于管理客户端与守护程序之间的通信。服务器在开发机器上作为后台进程运行。

ADB原理及启动流程

  1. 检查手机是否处于开发者模式
  2. shell 启动 adb 客户端进程
  3. 启动 adb 服务进程并连接
  4. adb 服务进程与设备的 adbd 进程建立连接
    在这里插入图片描述

adb 命令

  • 查看系统参数值:adb shell getprop system_prams

  • 查看屏幕密度:adb shell getprop ro.sf.lcd_density

  • 查看品牌:adb shell getprop ro.product.brand

  • 查看设备名:adb shell getprop ro.product.name

  • 设置系统参数值:adb shell setprop system_prams params_value

  • 重启:adb reboot

  • 查看日志:
    adb logcat > log.txt
    adb logcat | findstr “matched_string”

  • 安装/卸载
    adb install xxx.apk
    adb uninstall package_name

Android Studio 常用操作

创建模块

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

快捷键

常用

  1. Ctrl + Shift + F: 在整个项目中搜索。
  2. Ctrl + H:显示当前类的层次结构
  3. Ctrl + Alt + 空格 + 左右方向键:回退、前进 选定的代码

查找类型:

  1. Ctrl + F: 在当前文件中搜索。
  2. Ctrl + Shift + R: 全局替换。
  3. Shift + Shift: 全局搜索。
  4. Ctrl + Shift + F: 在整个项目中搜索。
  5. Ctrl + N: 查找类。
  6. Ctrl + Shift + N: 查找文件。

其他类型:

  1. Alt + Enter: 显示上下文菜单(Quick Fix,Intention Action)。
  2. Ctrl + Alt + L: 格式化代码。
  3. Ctrl + D: 复制当前行或选中的内容。
  4. Ctrl + /: 注释/取消注释当前行或选中的代码。
  5. Ctrl + Z: 撤销。
  6. Ctrl + Shift + Z: 重做。
  7. Ctrl + X: 剪切当前行或选中的内容。
  8. Ctrl + C: 复制当前行或选中的内容。
  9. Ctrl + V: 粘贴。
  10. Ctrl + Shift + 上箭头/下箭头: 上/下移当前行或选中的代码。
  11. Ctrl + Alt + 上箭头/下箭头: 上/下复制当前行或选中的代码。
  12. Ctrl + W: 逐渐扩大选中的范围(可在选中的单词、行、段落之间切换)。
  13. Ctrl + Shift + W: 逐渐减少选中的范围。
  14. Ctrl + E: 打开最近的文件列表。
  15. Ctrl + Shift + E: 打开最近的编辑过的文件列表。
  16. Ctrl + Alt + L: 格式化选中的代码。
  17. Ctrl + Alt + O: 优化导入的类和包。
  18. Ctrl + Space: 自动完成代码。
  19. Ctrl + Shift + Space: 强制类型提示(SmartType)。
  20. Ctrl + Alt + T: 包围选中的代码块(Surround with)。
  21. Alt + Insert: 生成代码(Generate)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值