天天看點

安卓開發(1)——安卓概述 - Sna1lGo

安卓開發(1)——安卓概述

安卓開發(1)——安卓概述

安卓簡介

安卓系統架構

安卓開發(1)——安卓概述 - Sna1lGo

也就是常說的四層架構:linux核心層(linux kernel),系統運作庫層(Library)、應用架構層(Application Framewordk)和應用層(Applications)。

Linux kernel

Linux核心層:這一層是為硬體提供底層的驅動,例如藍牙,Wi-Fi驅動等等。

Libraries

系統運作庫層:這一層通過C/C++庫來為Android系統提供了特性支援,來為上層提供支援。

Application Framework

主要提供了建構應用程式時可能用到的各種API。

Application

應用層,是以安裝在安卓手機上的應用程式都是屬于這一層的,比如手機上的一些聯系人,QQ,微信等應用。

安卓開發的四大元件

Activity,Service,BroadcastReceiver和ContentProvider。

Activity(活動):包含了所有在APP中可以看到的東西。

Service:是在背景運作的部分。

BroadcastReciver:廣播接受者,可以接受各處的廣播(如:短信,電話等等),也可以向外發出廣播。

ContentProvider:應用程式之間共享資料。(比如:微信通過讀取手機的聯系人來添加好友)

Android的開發環境

所需的工具:

JDK:用于處理java代碼。

AndroidSDK:是Google提供的Android開發工具包,提供Android要使用的API。

Android Studio:一個開發Android 的IDE。

如何搭建Android開發環境不是本部落格的重點,想了解的,可以自行百度搜尋。

第一個Android項目

建立項目

安卓開發(1)——安卓概述 - Sna1lGo

這裡選擇一個Empty Activity

安卓開發(1)——安卓概述 - Sna1lGo

這裡的Name就是app的名字,Package name是項目的包名,Android系統就是通過包名來區分不同的應用程式(application)的,是以包名必須得有唯一性。

Save Location表示項目儲存位址。

Language這裡可以選擇Kotlin和Java

Minimum SDK這裡可以設定項目的最低相容版本,也就是相容Android的最低版本為多少。

點選Finish就完成了第一個項目的建立

使用項目

建立虛拟機

Android系統開發的app,需要在Android系統上才能跑,Android Studio提供了Android的虛拟機,可以給我們用來測試APP。

安卓開發(1)——安卓概述 - Sna1lGo

在菜單中找到這三個案件,中間那個就是用來建立和啟動模拟器的。

然後開始建立模拟器:

安卓開發(1)——安卓概述 - Sna1lGo

這裡根據自己的喜好來選就好(我用的是Pixei2)

安卓開發(1)——安卓概述 - Sna1lGo

然後選擇系統鏡像,推薦選擇最新版本,也就是第一個,如果沒有下載下傳過該鏡像,需要點選Download後才能點選下一步。

安卓開發(1)——安卓概述 - Sna1lGo

使用虛拟機

安卓開發(1)——安卓概述 - Sna1lGo

單機想要啟動的虛拟機,就可以啟動該虛拟機了。

在虛拟機上運作寫好的項目app

先開啟虛拟機,開啟後,在該菜單欄裡面選擇要啟動的虛拟機和項目:

安卓開發(1)——安卓概述 - Sna1lGo

然後再點選右邊的運作按鈕就可以運作了。(左邊那個錘子是編譯項目的意思)

安卓開發(1)——安卓概述 - Sna1lGo

第一個Android項目就搞定了。

分析第一個Android程式

檢視項目檔案:

安卓開發(1)——安卓概述 - Sna1lGo

當一個項目建立的時候預設是采用Android模式的項目結構來檢視,但是這個步數真正的目錄結構,而是被Android Studio轉換了的,單擊Android轉換為Project(項目)版本來檢視(中英文可以能有出入)。

安卓開發(1)——安卓概述 - Sna1lGo

切換為project版本下的項目結構:

安卓開發(1)——安卓概述 - Sna1lGo

這個才是真實的項目結構。

分析項目檔案:

.gradle和.idea 存放的都是AS自動生成的檔案,這個不用處理。
app 項目中的代碼和資源等主要内容都是存放在這個目錄的,開發工作也主要是在這個目錄下面。
build 包含了一些在編譯時自動生成的檔案。(不用關心)
gradle 這個目錄包含了gradle wrapper的配置檔案,使用gradle wrapper的方式不需要提前将gradle下載下傳好,而是先根據有沒有本地緩存的情況來決定要不要下載下傳。可以點選File->Settings->Build,Execution,Deployment->Gradle。 整個安卓的項目都是采用gradle來全程把控
.gitignore 用來将指定的目錄或檔案排除在版本控制之外。
.build.gradle 全局的gradle建構腳本,通常是不用修改的。
gradle.properties 全局gradle的建構腳本,通常不需要修改。有點類似于makefile
gradlew和gradlew.bat 這兩個檔案是用來在指令行界面執行gradle指令的,其中gradlew是在linux上使用,gradlew.bat是用在windows系統上的。
HelloWorld.iml iml檔案是所有的IDEA項目都會自動生成的一個檔案(AS是基于IDEA開發的),該檔案隻是用來辨別是IDEA的項目檔案。
local.properties 該檔案用來指定Android 的SDK的路徑,通常是自動生成的,除非Android SDK位置發生變化,不然是不用修改的。
setting.gradle 用來指定項目中所有引入的子產品,通常情況下子產品的引入都是自動完成的,需要手動修改比較少。

分析app目錄

經過前面分析的項目檔案可以知道,除了app目錄,大部分檔案都是AS自動生成的,是以app檔案下的内容才是重點。

安卓開發(1)——安卓概述 - Sna1lGo
build 和外層的build一樣,包含的是一些編譯時自動生成的檔案。
libs 如果項目中包含了第三方的jar包,就需要把這些jar包放到libs檔案夾下
androidTest 用來寫Android Test測試用例的
java 放置所有java(Kotlin)代碼的,展開可以看到,AS自動生成了一個MainActivity檔案
res 在項目裡使用的所有圖檔、布局、字元串等資源都要存放到該目錄下。圖檔放到drawable目錄下,布局放到layout目錄下,字元串放到value目錄下。
AndroidManifest.xml 整個項目的配置檔案,在程式中定義的所有四大元件都需要在這個檔案裡面注冊,還可以在這裡面給應用程式添權重限聲明。
test 用來編寫Unit Test測試用例,對項目進行自動化測試的一種方式。
.gitignore 用于将app子產品内指定的目錄或檔案排除在版本控制之外。
app.iml IDEA自動生成的檔案,僅僅來辨別是個IDEA檔案。
build.gradle app子產品内部的gradle建構腳本,指定很多項目建構相關的配置。
proguard-rules.pro 用于指定項目代碼的混淆規則,當代碼開發完成後,不希望被别人破解,通常會将代碼進行混淆,

詳解app中的res

安卓開發(1)——安卓概述 - Sna1lGo

将res檔案夾展開可以看到裡面的檔案還是挺多的,但是歸納一下就還好。

圖檔 所有以drawable開頭的目錄都是用來存放圖檔的
應用圖示 所有以mipmap開頭的存放的都是應用圖示
配置 所有以values開頭的都是用來存放字元串、樣式、顔色等配置的。
布局 所有以layout開頭的目錄都是用來存放布局檔案的。

之是以有這麼多mipmap開頭的目錄,主要是為了相容各種裝置,drawable也是一樣,雖然AS沒有自動生成,但是為了更好相容,我們也應該自己建立drawable-hdpi ... drawable-xxxhdpi等目錄。在寫程式的時候最好對同一個圖檔能提供幾個不同分辨率的版本,分别放在這些目錄下面,但是大多數時候隻會有一個圖檔,就把所有的圖檔放到drawable-xxxhdpi裡面就好了,這個目錄對應的是最主流的裝置分辨率。

安卓開發(1)——安卓概述 - Sna1lGo

打開values下的string,xml:

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

可以看到這裡定義了一個應用程式名字的字元串,有兩種方式可以拿來引用它:

1:在代碼裡面通過R.string.app_name可以獲得該字元串的引用

2:在X M L中通過 @string/app_name可以獲得該字元串的引用

其中的string部分是可以替換的,如果用的是圖檔資源就可以替換成drawable,如果是應用圖示就可以替換成mipmap,布局檔案就可以替換成layout

例如:AndroidManifest.xml檔案中的内容

   <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.HelloWorld">
        ....
        </activity>
    </application>      

詳解build.gradle檔案

AS采用gradle來建構項目,gradle是一個比較先進的項目建構工具,基于Groovy領域特點語言來進行項目設定,抛棄了基于傳統的XML的各種繁瑣配置。(反正比較先進就行了。)

在我們這個HelloWorld項目中,有兩個build.gradle檔案,一個是整體的build.gradle,一個是app目錄下的build.gradle檔案。

詳解整體項目的build.gradle檔案

先看整體項目的build.gradle檔案:

buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
​
allprojects {
    repositories {
        google()
        jcenter()
    }
}      

這些代碼都是自動生成的,看似複雜但是忽略文法檢視關鍵代碼還是挺簡單的。

首先兩處的repositories都聲明了google()和jcenter(),這兩個分别對應兩個代碼倉庫,google()主要是包含谷歌自己的擴充依賴庫,jcenter()主要是包含一些開源的第三方庫,聲明了之後就可以使用它們所包含的依賴庫了。

在dependencies中聲明了gradke和kotlin的兩個插件,申明gradle是因為gradle并不是專門給Android開發出來的,如果要使用的話,肯定需要聲明gradle的插件,gradle後面的版本通常是和AS的版本相對應的,申明kotlin是因為這個Android項目是用的kotlin語言,如果采用的是java的話就不會有這個了。

詳解app下的build.gradle檔案

檢視app下的build.gradle源代碼:

plugins {
    id \'com.android.application\'
    id \'kotlin-android\'
}
android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
    defaultConfig {
        applicationId "com.example.helloworld"
        minSdkVersion 21
        targetSdkVersion 30
        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
    }
    kotlinOptions {
        jvmTarget = \'1.8\'
    }
}
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation \'androidx.core:core-ktx:1.2.0\'
    implementation \'androidx.appcompat:appcompat:1.1.0\'
    implementation \'com.google.android.material:material:1.1.0\'
    implementation \'androidx.constraintlayout:constraintlayout:1.1.3\'
    testImplementation \'junit:junit:4.+\'
    androidTestImplementation \'androidx.test.ext:junit:1.1.1\'
    androidTestImplementation \'androidx.test.espresso:espresso-core:3.2.0\'
}      

第一個閉包plugins:

com.android.application:表示是一個應用程式子產品。 kotlin-android:就是一個kotlin的插件,如果要用kotlin來開發,這個插件是必須要的。

第二個閉包是一個很大的閉包 Android,該閉包中嵌套了defaultConfig,buildTypes,compileOptions,kotlinOptions 四個閉包。在Android閉包裡面可以配置項目建構的各自屬性,其中compileSdkVersion用來指定項目的編譯版本,指定Android項目的SDK版本,buildToolsVersion用來指定項目建構工具的版本。

Android閉包裡的defaulltConfig閉包:

       applicationId "com.example.helloworld"  //每個應用的唯一辨別符,也就是在建立項目時的包名
        minSdkVersion 21    //項目最低相容的Android版本
        targetSdkVersion 30 //該字段指定的值用來表示在目前目标版本上已經做好了充分的測試
//指定的值表示在哪一個sdk版本以及之前已經做好了充分的測試。
        versionCode 1   //指定項目的版本号
        versionName "1.0"   //指定項目的版本名
​
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        //用來在目前項目中七點JUnit測試      

Android閉包裡的buildTypes閉包:

buildTypes閉包裡通常會有兩個子閉包,release和debug,就相當于項目的兩個版本,debug預設可以不用寫。

   buildTypes {
        release {
            minifyEnabled false //用來指定是否對項目的代碼進行混淆
            proguardFiles getDefaultProguardFile(\'proguard-android-optimize.txt\'), \'proguard-rules.pro\' //proguardFiles用來指定代碼的混淆規則
//proguard-android-optimize.txt是在<AndroidSDK>/tools/proguard目錄下的一個通用混淆規則
//proguard-rules.pro是在目前項目的根目錄下的,裡面可以編寫目前項目特有的代碼混淆規則
        }
    }      

Android剩下的兩個閉包:compileOptions,kotlinOptions都是用來指定java和jvm版本的,沒啥影響。

最後一個閉包:dependencies,這個閉包指定了項目的所有依賴關系。

在Android中的依賴有三種方式:本地依賴,庫依賴,遠端依賴。本地依賴可以對本地的jar包添加,庫依賴可以對項目中的庫子產品添加依賴,遠端依賴則是對于jcenter倉庫上的開源項目進行添加依賴。

implementation fileTree 是本地依賴申明
implementation 表示是一個遠端依賴
implementation project  表明是一個庫依賴      
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation \'androidx.core:core-ktx:1.2.0\'
    implementation \'androidx.appcompat:appcompat:1.1.0\'//一個标準的遠端依賴
    //androidx.appcomat是域名用來區分其他公司的庫,appcompat是工程名,1.1.0是版本号。
    implementation \'com.google.android.material:material:1.1.0\'
    implementation \'androidx.constraintlayout:constraintlayout:1.1.3\'
    testImplementation \'junit:junit:4.+\'
    androidTestImplementation \'androidx.test.ext:junit:1.1.1\'
    androidTestImplementation \'androidx.test.espresso:espresso-core:3.2.0\'
}      

分析一個項目的運作流程

分析一下,這裡寫的Helloworld項目是如何運作起來的。

首先檢視AndroidManifest.xml檔案,找到如圖所示的代碼:

安卓開發(1)——安卓概述 - Sna1lGo
       <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>      

這段代碼表示對MainActivity的注冊(沒有再AndroidManifest.xml檔案中注冊的四大元件是無法使用的),其中intent-filter代碼段裡面的兩行代碼最為重要,其作用就是表示MainActivity是這個項目的主Activity,在手機上點選應用圖示,首先啟動的就是該Activity。

凡是在APP中可以看到的東西,都是Android中的四大元件的Activity中的内容,是以在該HelloWorld項目中看到的彈出來的界面就是MainActivity,檢視MainActivity的代碼:

安卓開發(1)——安卓概述 - Sna1lGo
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}      

可以很清楚地看到MainActivity是繼承了AppCompatActivity這個類的。AppCompatActivity是AndroidX提供的一個向下相容的Activity,可以讓Activity在不同系統版本中的功能保持一緻性。而Activity是Android提供的一個Activity基類,所有自己自定義的Activity都需要繼承于它或它的子類(AppCompatActivity就是它的子類)。然後可以看到該MainActivity類有一個onCreate()函數,這個方法是Activity元件建立時必須要執行的方法,而且隻有兩行代碼,可以看到這裡并沒有我們使用該APP顯示的HelloWorld字元串,那麼顯示的HelloWorld到底在哪裡呢?

Android程式設計講究邏輯和視圖分離, 是以一般不要再Activity裡面直接編寫界面加邏輯的,更加通用的辦法是:在布局檔案中編寫界面,然後再在Activity中引入進來。

在MainActivity類中的onCreate()方法中的第二行調用了setContentView()方法,就是這個方法給目前的Activity引入了一個activity_main布局,那麼“Hello World!”就一定在該R.layout.activity_main裡面定義的,前面有提到所有的資源在res下,所有的布局檔案又在res下的layout裡面,是以直接去檢視布局檔案:

安卓開發(1)——安卓概述 - Sna1lGo

切換成code(代碼)視角:

安卓開發(1)——安卓概述 - Sna1lGo
<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">
​
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
​
</androidx.constraintlayout.widget.ConstraintLayout>      

這裡的Textview代碼段裡面,有一行android:text=".....",就是這裡我們想要的Hello World。

總結一個項目的運作流程:進入一個app首先是擷取AndroidManifest.xml檔案中注冊的Activity元件,然後看到的是Activity裡面的MainActivity,就好比一個C語言程式裡面的main函數,然後根據MainActivity裡面的代碼邏輯擷取得到布局檔案最後展示出來。

如何使用日志工具

在Android裡面的日志工具是非常重要的,特别是對于開發者來說,是非常重要的。

Android中的日志工具類是Log(android.util.Log),提供了5個方法來列印日志:

Log.v() 列印最低級别的日志,對應級别是verbose
Log.d() 列印一些調試資訊,對應級别是debug,比verbose高一級
Log.i() 列印一些比較重要的資訊,可以分析使用者行為的資料,對應級别為info,比debug高一級
Log.w() 列印警告資訊,對應級别為warn比info高一級
Log.e() 列印錯誤資訊,對應級别為error

在helloworld項目中使用日志工具:在MainActivity.kt裡面添加Log.d("MainActivity","onCreate execute")

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d("MainActivity","onCreate execute")
    }
}      
安卓開發(1)——安卓概述 - Sna1lGo

再在Logcat下面就可以看到日志資訊了。

通過過濾器來檢視不同的Log資訊。

總結

使用kotlin來開發Android已經大勢所趨了,安卓開發的細節,以及配置檔案很多,比較麻煩,這一章節看完了相當于有一個大概的輪廓了。

posted on

2021-05-28 20:07 

Sna1lGo 

閱讀(1246) 

評論(0) 

編輯 

收藏 

舉報