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


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

安卓簡介

安卓系統架構

Android系統結構

也就是常說的四層架構: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項目

創建項目

 

 

這里選擇一個Empty Activity

 

 

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

Save Location表示項目保存地址。

Language這里可以選擇Kotlin和Java

Minimum SDK這里可以設置項目的最低兼容版本,也就是兼容Android的最低版本為多少。

點擊Finish就完成了第一個項目的創建

使用項目

創建虛擬機

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

 

 

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

然后開始創建模擬器:

 

 

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

 

 

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

 

 

 

使用虛擬機

 

 

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

在虛擬機上運行寫好的項目app

先開啟虛擬機,開啟后,在該菜單欄里面選擇要啟動的虛擬機和項目:

 

 

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

 

 

 

 

第一個Android項目就搞定了。

分析第一個Android程序

查看項目文件:

 

 

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

 

 

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

 

 

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

分析項目文件:

.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文件下的內容才是重點。

 

 

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

 

 

將res文件夾展開可以看到里面的文件還是挺多的,但是歸納一下就還好。

圖片 所有以drawable開頭的目錄都是用來存放圖片的
應用圖標 所有以mipmap開頭的存放的都是應用圖標
配置 所有以values開頭的都是用來存放字符串、樣式、顏色等配置的。
布局 所有以layout開頭的目錄都是用來存放布局文件的。

之所以有這么多mipmap開頭的目錄,主要是為了兼容各種設備,drawable也是一樣,雖然AS沒有自動生成,但是為了更好兼容,我們也應該自己創建drawable-hdpi ... drawable-xxxhdpi等目錄。在寫程序的時候最好對同一個圖片能提供幾個不同分辨率的版本,分別放在這些目錄下面,但是大多數時候只會有一個圖片,就把所有的圖片放到drawable-xxxhdpi里面就好了,這個目錄對應的是最主流的設備分辨率。

 

 

打開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文件,找到如圖所示的代碼:

 

 

        <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的代碼:

 

 

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里面,所以直接去查看布局文件:

 

 

切換成code(代碼)視角:

 

 

<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")
  }
}

 

 

再在Logcat下面就可以看到日志信息了。

通過過濾器來查看不同的Log信息。

 

總結

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM