Android第一行代码学习笔记【第一章】

Android第一行代码


第1章 开始启程

1.1 Android系统架构

  1. Linux Kernel:为Android设备提供了各种硬件的底层驱动;
  2. Libraries:C/C++库为Android系统提供主要特性支持;还有Android Runtime(安卓运行时)库;
  3. Application Framwork:提供构建App时可能用到的各种API;
  4. Applications:所有应用程序都在这一层。

1.2 Android 应用开发特色

  1. 四大组件:
    • Activity:所有应用程序的门面。凡是在App种看得到的东西,都是放在Activitiy中的;
    • Service:在后台运行。即使用户退出应用,也可以继续运行;
    • BroadcastReceiver:允许应用接受来自各处的广播;也可以向外发出广播信息;
    • ContentProvider:帮助应用程序之间共享数据。例如想读取通讯录中的联系人,就需要ContentProvider来实现。
  2. 系统控件
  3. SQLite数据库
  4. 多媒体

1.3 创建Android项目

  • Name:项目名称
  • Package Name:项目的包名。Android系统通过不同的报名来区分不同的应用程序

1.4 分析Android项目结构

  • .gradle和.idea:AS自动生成的文件,无需关心;
  • app:包括项目中的代码、资源等内容;
  • build:编译时自动生成的文件,无需关心;
  • gradle:包含gradle wrapper的配置文件;gradle是用来自动构建各种项目的工具,gradle wrapper是根据缓存情况,自动将gradle下载好,免去因版本问题等需要手动配置的麻烦;
  • .gitgnore:用来将指定的目录或文件排除在版本控制之外;(版本控制在第六章)
  • build.gradle:项目全局的gradle构建脚本,通常不需要修改;(后面有详细介绍)
  • gradle.properties:全局的gradle配置文件,其属性会影响项目中所有的gradle编译脚本;
  • gradlew和gradle.bat:用来在命令行界面中执行gradle命令。前者is for mac/linux,后者for windows;
  • .iml:所有IntelliJ IDEA项目都会自动生成这样一个文件(AS是基于IntelliJ IDEA开发的),用于标识,无需修改;
  • local.properties:用于指定本机中的Android SDK路径,内容通常是自动生成的,无需修改;
  • settings.gradle:用于指定项目中所有引入的模块。通常情况下模块的引入是自动完成的;
1.4.1 app目录下的内容

这部分内容才是工作重点,以下是详细分析。

  • build:与外层的build目录类似,无需关心;
  • libs:存储第三方jar包。此目录下的jar包会被自动添加到项目的构建路径里;
  • androidTest:用来编写Android Test测试用例的,可以对项目进行一些自动化测试;
  • java:放置所有java (Kotlin)代码的地方;
  • res:存储项目中所有的图片(drawable)、布局(layout)、字符串(values)等资源;
  • AndroidManifest.xml:整个Android项目的配置文件。注册组件、添加权限声明;
  • test编写Unit Test测试用例,另一种自动化测试的方式;
  • .gitnore:将app模块内指定的目录或文件排除在版本控制之外;
  • app.iml:自动生成的文件,无需关心;
  • build.gradle:app模块的gradle构建脚本;
  • proguard-rules.pro:指定代码的混淆规则。当代码开发完成后打包成安装包文件,如果不希望被别人破解,通常会将代码进行混淆,从而使破解者难以阅读;
1.4.2 HelloWorld项目是如何运行起来的?

首先看AndroidManifest.xml中的这段代码:

         <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyHelloWorld">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

这段代码表示对MainActivity进行注册,必须先注册才能使用。其中intent-filter中的两行代码表示MainActivity是这个项目的主Activity,在手机上打开应用,首先启动的就是这个Activity。

MainActivity.kt中的这段代码:

class MainActivity : ComponentActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContent {
    
    
            MyHelloWorldTheme {
    
    
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
    
    
                    Greeting("Android")
                }
            }
        }
    }
}

书上的代码第一行是class MainActivity : AppCompatActivity() { ,意思是MainActivity是继承自AppCompatActivity的。这是AndroidX中提供的一种向下兼容的Activity。项目中所有自定义的Activity都必须继承它或它的子类才能拥有Activity的特性(AppCompatActivityComponentActivity都是Activity的子类)。

onCreate()方法:一个Activity被创建时必定要执行的方法。

书上说“Android程序的设计讲究逻辑和视图分离,因此不推荐在Activity中直接编写界面”。书中的示例代码是通过setContentView()方法给当前的Activity引入了一个activity_main布局,该布局文件位于res/layout目录下。

不过经过寻找,我并没有在res目录下找到layout文件夹。

1.4.3 详解res目录
  • drawable:放图片的;
  • mipmap:放应用图标的;
  • values:放字符串、样式、颜色等配置的;
  • layout:放布局文件的;
    有很多mipmap开头的文件是为了让程序更好地兼容各种设备,drawabl也同理。(最主流的设备分辨率目录:drawable-xxhdpi)

如何使用res里的各种资源?
举个例子,在res/values/strings.xml文件中有如下代码:

<resources>
    <string name="app_name">MyHelloWorld</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.MyHelloWorld"
        tools:targetApi="31">
        ...
    </application>

正是上文的XML引用方式。

1.4.4 详解build.gradle文件

Gradle是一种非常先进的项目构建工具。外层的gradle文件主要声明了gradle插件和kotlin插件,包括它们各自的版本。通常情况下并不需要修改外层的gradle文件。

书中的版本与现在的版本有区别。现在的gradle文件叫做build.gradle.kts,使用Kotlin编写,是目前默认的格式。书中的build.gradle文件是较旧版本。

内层的gradle文件就比较复杂了。

plugins {
    
    
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

这部分应用了两个插件。第一个应用的插件一般有两种值可选:com.android.application(表示这是一个应用程序模块)和com.android.library(表示这是一个库模块)。前者可以直接运行,后者只可以作为代码库依附于别的应用程序模块运行。第二行代码应用了kotlin插件。这是用Kotlin开发Android项目所必需的插件。

android闭包中,又有以下几个闭包:(以下用ita程序中的代码作为实例,而不是MyHelloWorld)

  1. defaultConfig

    defaultConfig {
          
          
        applicationId 'com.bh.ita'
        minSdk 26
        targetSdk 34
        versionCode 8
        versionName '1.0.8'
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    

    defaultConfig可以对项目的更多细节进行配置,其中:

    • applicationID是每一个应用的唯一标识符,绝不可重复;
    • minSDKVersion指定项目最低兼容的Android系统版本;
    • targetSDKVersion指定的值表示你在该目标版本上已做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性;
    • versionCodeversionCode:指定项目的版本号/版本名;
    • testInstrumentationRunner用于在当前项目中启用JUnit测试,你可以为当前项目编写测试用例,以保证功能的正确性和稳定性。
  2. buildTypes

    buildTypes {
          
          
        release {
          
          
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    

    该闭包只会有两个子闭包:debud和release。前者用于指定生成测试版安装文件的配置,后者用于生 成正式版安装文件的配置。其中debug闭包是可以忽略不写的。在release闭包中:

    • minifyEnabled:用于指定是否对项目的代码进行混淆;
    • proguardFiles:用于指定混淆时使用的规则文件。'proguard-android-optimize.txt’在…/tools/proguard目录下,是所有项目通用的混淆规则;第二个proguard-rules.pro在当前项目根目录下,里面可以编写当前项目特有的混淆规则。

    通过AS直接运行项目生成的都是测试版安装文件。如何生成正式版安装文件见第十五章。

接下里是dependencies闭包,可以指定当前项目所有的依赖关系。通常AS项目一共有三种依赖关系:

  • 本地依赖:对本地的jar包或目录添加依赖关系(implementation filetree);
  • 库依赖:对项目中的库模块添加依赖关系(implementation project);
    例如,implementation project(':helper')就可以添加helper库的依赖关系了。
  • 远程依赖:对jcenter仓库上的开源项目添加依赖关系(implementation)。
    例如, implementation("androidx.core:core-ktx:1.9.0")中,androidx.core是域名部分,用于和其他公司的库做区分;core-ktx是工程名部分,与同公司不同库工程做区分;1.9.0是版本号,与同一个库不同版本做区分。加上这句声明后,Gradle就会在构建项目前首先检查一下本地是否已经有这个库的缓存,没有就会联网下载然后再添加道项目的构建路径中去。

1.5 日志工具

Android中的日志工具类是Log (andorid.util.Log),有以下五个方法来打印日志:
参数都是(‘tag’, ‘msg’)。前者一般传入当前的类名即可,主要用于对打印信息进行过滤;后者是想要打印的具体内容。

  • Log.v( ): verbose,最为琐碎、意义最小;
  • Log.d( ): debug。用于打印一些调试信息;
  • Log.i( ): info。用于打印一些比较重要的数据;
  • Log.w( ): warn。用于打印警告信息,潜在风险;
  • Log.e( ): error。打印错误信息。当有错误信息被打印出时,一般意味着程序出现严重问题。
    例如在onCreate函数中写Log.d("MainActivity", "onCreate execute"),运行程序后即可在底部Logcat中查看到输出的日志。可以通过过滤器,查看不同条件下的日志,从而快速找出想要的信息。(比println好的原因之一)

猜你喜欢

转载自blog.csdn.net/qq_58325158/article/details/135451945