Android基礎教程 - 學習完成記錄

視頻學習教程

視頻鏈接:2022 最新 Android 基礎教程,從開發入門到項目實戰,看它就夠了,更新中_嗶哩嗶哩_bilibili

學習下來,有遇到很多問題,在 chatgpt、claude 和 Android Studio 插件通義千問的幫助下,一一解決。

目前還是有很多不懂的,雖然學了一遍,敲了一遍,但是 Android 體系還是太多,需要不斷地學習。

Gitee 地址

代碼均可以跑通,視頻中項目實戰均實現。
Magnolia/AndroidLearning
如果可以,幫點個小星星,謝謝~


下面是一些記錄。

資源IDs 變成 non-final

Resource IDs will be non-final by default in Android Gradle Plugin version 8.0, avoid using them in switch case statements.

在 Android Gradle Plugin 8.0 中,資源 ID 默認變為 non-final,意思是它們不再是編譯時常量,而是動態生成的。這是因為 Android 的資源 ID 現在默認使用了新的構建優化方式,使得每次構建時資源 ID 可能發生變化,從而減少了重編譯時間,但也帶來了以下變化:

解釋 non-final

  • 原本的 final 行為:在 Android Gradle Plugin 8.0 之前,資源 ID(如 R.id.example_button)被編譯成 final 常量(不可變的靜態值),因此可以直接用于 switch 語句,因為編譯器在編譯時可以確定它們的值。
  • non-final 意味著動態生成:從 8.0 開始,資源 ID 不再是 final 的。它們的值在每次構建時可能會動態生成,無法在編譯時確定。因此,在 switch 語句中使用這些非固定值會導致編譯錯誤,因為 switch 語句要求常量。

影響和替代方案

由于資源 ID 變為 non-final,在 Android Gradle Plugin 8.0+ 中,不能在 switch 語句中使用它們。可以使用 if-else 結構來替代 switch

變量聲明為 final

將變量聲明為 final 有以下好處:

  • 不可變性:確保該變量在初始化后不能被修改,提高代碼的安全性和可預測性。
  • 線程安全:在多線程環境中,final 變量可以避免多個線程同時修改同一個變量帶來的問題。
  • 優化:編譯器可以對 final 變量進行一些優化,提高性能。
private String mRequest = "你好,在嗎?";
// 可以寫成:
private final String mRequest = "你好,在嗎?";

override 注解

@Override 注解在 Java 中用于表示一個方法是在重寫父類或實現接口中的方法。使用 @Override 有以下幾個好處:

  • 提高可讀性:明確告知其他開發者這個方法是一個重寫的方法。
  • 編譯器檢查:如果方法簽名與父類或接口中的方法不匹配,編譯器會報錯,幫助開發者發現潛在的錯誤。

如果不加 @Override 注解,代碼仍然可以正常編譯和運行,但會有以下問題:

  • 缺乏明確性:其他開發者閱讀代碼時可能不清楚這個方法是否是重寫的。
  • 潛在錯誤:如果方法簽名寫錯了(例如拼寫錯誤或參數類型不匹配),編譯器不會報錯,但方法不會被正確調用,導致難以調試的問題。

.9.png

在 Android 開發中,.9.png 是一種特殊的圖片格式,稱為 Nine-Patch (九宮格) 圖片。這種格式的圖片在 .png 圖片基礎上做了特殊處理,主要用于實現拉伸和縮放效果,適應不同尺寸的屏幕和控件。

特點與用途

  1. 靈活拉伸:Nine-Patch 圖片可以指定哪些區域可被拉伸,哪些區域保持不變。這對于按鈕、對話框背景等需要根據內容大小動態調整的控件非常有用。
  2. 邊界標記:Nine-Patch 圖片的邊界上有一像素寬的黑色線條,Android 會根據這些標記確定哪些部分可以拉伸,哪些部分保持原樣。具體來說:
    • 左側和上側邊界:定義圖片可以被拉伸的區域。
    • 右側和下側邊界:定義內容顯示區域。
  3. 高效適配:Nine-Patch 圖片在適應不同分辨率和屏幕尺寸時,不會失真或模糊,提供較好的視覺效果。適合用于各種彈窗、輸入框背景、氣泡等需要拉伸的圖形背景。

示例應用

  • 按鈕背景、輸入框背景、對話框背景等需要根據內容大小動態變化的 UI 元素。

創建方法

Nine-Patch 圖片可以通過 Android Studio 的 Draw 9-Patch 工具制作,或直接在圖片上手動添加一像素的黑色邊界。Android 會根據這些邊界像素的標記進行渲染處理。

Nine-Patch 圖片通過簡單的標記,能以更小的資源量適配不同屏幕,是一種高效的圖片處理方式。

復合按鈕

由復合按鈕 CompoundButton 派生而來的控件包括:CheckBoxRadioButtonSwitch

導入 Nullable

import androidx.annotation.Nullable;

作用是導入 Nullable 注解。這個注解來自 AndroidX 庫,用于標記方法參數、返回值或字段,表示它們可以為 null

  • 代碼可讀性:提高代碼的可讀性和維護性,明確指出某個變量或參數可以為 null
  • 靜態分析:幫助 IDE 和靜態代碼分析工具進行更準確的檢查,減少潛在的空指針異常。

示例

@Nullable
public String getName() {return name;
}

在這個示例中,@Nullable 注解表明 getName 方法的返回值可以為 null

Boolean 與 boolean

Boolean married = ck_married.isChecked(); 
boolean married = ck_married.isChecked(); 這兩種寫法有什么區別?
  1. Boolean married = ck_married.isChecked();

    • 類型Booleanboolean 的包裝類。
    • :可以為 truefalsenull
    • 使用場景:適用于需要表示 null 值的情況,例如在集合中存儲布爾值或處理可能為 null 的返回值。
  2. boolean married = ck_married.isChecked();

    • 類型boolean 是基本數據類型。
    • :只能為 truefalse
    • 使用場景:適用于不需要表示 null 值的情況,性能更好,占用內存更少。

在代碼中:

  • Boolean married = ck_married.isChecked();:這里 married 變量可以為 truefalsenull。但由于 isChecked() 方法總是返回 truefalse,所以 married 不會為 null
  • boolean married = ck_married.isChecked();:這里 married 變量只能為 truefalse,更符合實際需求,因為 isChecked() 方法不會返回 null

推薦做法

在大多數情況下,特別是當你確定變量不會為 null 時,推薦使用基本數據類型 boolean,因為它更高效且占用內存更少。

boolean married = ck_married.isChecked();

總結

  • Boolean:包裝類,可以為 null
  • boolean:基本數據類型,不能為 null
  • 推薦:在不需要表示 null 值的情況下,使用 boolean

參數化查詢和靜態查詢

參數化查詢

String sql = "select * from " + TABLE_NAME + " where phone=? and remember=1";
Cursor cursor = mRDB.rawQuery(sql, new String[]{phone});
  1. SQL 查詢:

    • select * from <TABLE_NAME> where phone=? and remember=1:這條 SQL 語句從表中選擇所有列,條件是 phone 等于某個值且 remember 等于 1。
    • ? 是一個占位符,用于防止 SQL 注入攻擊。
  2. 參數化查詢:

    • new String[]{phone}:這是一個字符串數組,包含一個元素 phone。這個數組中的值會替換 SQL 語句中的 ? 占位符。
    • 例如,如果 phone 的值是 "1234567890",那么最終的 SQL 語句會變成 select * from <TABLE_NAME> where phone='1234567890' and remember=1

靜態查詢

String sql = "select * from " + TABLE_NAME + " where remember=1 order by _id desc limit 1";
Cursor cursor = mRDB.rawQuery(sql, null);
  1. SQL 查詢:

    • select * from <TABLE_NAME> where remember=1 order by _id desc limit 1:這條 SQL 語句從表中選擇所有列,條件是 remember 等于 1,并按 _id 列降序排列,只取第一行。
    • 沒有使用占位符 ?,因為查詢條件中沒有動態參數。
  2. 參數化查詢:

    • null:表示沒有參數需要傳遞給 SQL 語句。

為什么前者多了 new String[]{phone}

  • 參數化查詢:new String[]{phone} 用于傳遞動態參數 phone 給 SQL 語句中的占位符 ?。這樣做可以防止 SQL 注入攻擊,提高安全性。
  • 靜態查詢:第二段代碼沒有動態參數,因此不需要傳遞參數數組,直接使用 null 即可。

總結

  • 第一段代碼:使用參數化查詢,動態傳遞 phone 參數。
  • 第二段代碼:使用靜態查詢,沒有動態參數。

android.intent.action.VIEW

"android.intent.action.VIEW" 或者 "android.intent.action.ACTION_VIEW" 都可以

Intent intent = new Intent(Intent.ACTION_VIEW);
<activityandroid:name=".ThirdActivity"android:exported="false"tools:ignore="AppLinkUrlError"><intent-filter><action android:name="android.intent.action.ACTION_VIEW" /><category android:name="android.intent.category.DEFAULT" /><data android:scheme="http" /></intent-filter>
</activity>

簡要解釋原因

在 Android 中,Intentaction 屬性用于指定操作類型。"android.intent.action.VIEW""android.intent.action.ACTION_VIEW" 實際上是同一個常量的不同表示形式。

  • "android.intent.action.VIEW":這是直接使用字符串形式的 action 名稱。
  • "android.intent.action.ACTION_VIEW":這是通過 Intent 類中的靜態常量 Intent.ACTION_VIEW 來引用的。

這兩種方式在功能上是等價的,因為它們都指向同一個標準的 Android 操作名稱 "android.intent.action.VIEW"

分點描述

  • 字符串形式 vs 常量形式

    • 使用字符串形式(如 "android.intent.action.VIEW")時,代碼更直觀,但容易出現拼寫錯誤。
    • 使用常量形式(如 Intent.ACTION_VIEW)時,代碼更安全,編譯器可以進行類型檢查和自動補全,減少錯誤。
  • 推薦使用常量形式

    • 使用常量形式可以提高代碼的可讀性和維護性。
    • 編譯器可以在編譯時檢查常量的有效性,避免運行時錯誤。

示例代碼

AndroidManifest.xml 中使用常量形式

<activityandroid:name=".ThirdActivity"android:exported="false"tools:ignore="AppLinkUrlError"><intent-filter><action android:name="android.intent.action.VIEW" /><!-- 或者使用 --><action android:name="android.intent.action.ACTION_VIEW" /><category android:name="android.intent.category.DEFAULT" /><data android:scheme="http" /></intent-filter>
</activity>

在 Java 代碼中使用常量形式

else if (v.getId() == R.id.btn_jump2web) {Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);
}

雖然 "android.intent.action.VIEW""android.intent.action.ACTION_VIEW" 都可以正常工作,但建議使用常量形式 Intent.ACTION_VIEW,以提高代碼的安全性和可維護性。


Bug記錄

購物車數目只更新一次
    private void addToCart(int goodsId, String goodsName) {int goodsCount = MyApplication.getInstance().goodsCount;++goodsCount;tv_count.setText(String.valueOf(goodsCount));mDBHelper.insertCardInfo(goodsId);ToastUtil.show(this, "已添加一件" + goodsName + "到購物車");}

原因:僅對局部變量 goodsCount 進行自增操作,此時MyApplication.getInstance().goodsCount的值并沒有被修改,首次操作時, goodsCount 加一了,所以購物車數目會加一。但是,后面再添加就不會更新,因為每次獲取的 goodsCount 都是一樣的值,tv_count 更新也都是第一次更新的數字。

先對MyApplication.getInstance().goodsCount進行自增操作,然后將自增后的結果賦值給goodsCount,確保MyApplication.getInstance().goodsCount 和UI顯示同步更新。

    private void addToCart(int goodsId, String goodsName) {int goodsCount = ++MyApplication.getInstance().goodsCount;tv_count.setText(String.valueOf(goodsCount));mDBHelper.insertCardInfo(goodsId);ToastUtil.show(this, "已添加一件" + goodsName + "到購物車");}

問題處理

Run后模擬器未啟動app

可能的原因或者解決方法

  • 模擬器是否多開,在另一個中啟動

  • 重啟模擬器,清除模擬器數據(wipe data)后重啟

  • adb devices 查看狀態

    如果是 unauthorized,嘗試 adb kill-server, adb start-server,設置 cold boot 啟動

  • 查看 AndroidManifest.xml 是否配置正確

模擬器進程被占用

AVD Pixel_2_API_31 is already running. If that is not the case, delete the files at D:\software\Android.android\avd/Pixel_2_API_31.avd/*.lock and try again.

taskkill /F /IM qemu-system-* /IM emulator-* /IM adb.exe
del /F /Q D:\software\Android\.android\avd\Pixel_2_API_31.avd\*.lock

使用 procexp.exe 找到并結束進程。


記錄

AndroidStudio 中, debug 運行代碼,生成包 build/intermediates/apk/debug/chapter06-debug.apk

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77162.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77162.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77162.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Web開發-JavaEE應用原生和FastJson反序列化URLDNS鏈JDBC鏈Gadget手搓

知識點&#xff1a; 1、安全開發-JavaEE-原生序列化-URLDNS鏈分析 2、安全開發-JavaEE-FastJson-JdbcRowSetImpl鏈分析 利用鏈也叫"gadget chains"&#xff0c;我們通常稱為gadget&#xff1a; 1、共同條件&#xff1a;實現Serializable或者Externalizable接口&…

OpenCV操作函數

1、cv2.imread&#xff08;&#xff09; 2、 cv2.imshow&#xff08;&#xff09; 3、 cv2.waitKey&#xff08;&#xff09; 4、cv2.imwrite&#xff08;&#xff09; 5、cv2.selectROI&#xff08;&#xff09; 6、 cv2.VideoCapture() 7、cv2.cvtColor&#xff08;&#xff…

AI編程新紀元:GitHub Copilot、CodeGeeX與VS2022的聯合開發實踐

引言:AI編程時代的到來 在軟件開發領域,我們正站在一個歷史性的轉折點上。GitHub Copilot、CodeGeeX等AI編程助手的出現,結合Visual Studio 2022的強大功能,正在重塑代碼編寫的本質。這不僅是工具層面的革新,更是開發范式的根本轉變。能夠有效利用這些AI工具的開發者將跨…

[特殊字符] MySQL MCP 開發實戰:打造智能數據庫操作助手

&#x1f4a1; 簡介&#xff1a;本文詳細介紹如何利用MCP&#xff08;Model-Control-Panel&#xff09;框架開發MySQL數據庫操作工具&#xff0c;使AI助手能夠直接執行數據庫操作。 &#x1f4da; 目錄 引言MCP框架簡介項目架構設計開發環境搭建核心代碼實現錯誤處理策略運行和…

Dify部署過程中的錯誤和解決方案匯總

本文僅限于記錄Dify部署及使用過程中的BUG和解決方案 1. Dify配置SearXNG時報錯&#xff1a; 報錯內容&#xff1a; PluginInvokeError: {"args":{},"error_type":"ToolProviderCredentialValidationError","message":"Error 4…

C#中async await異步關鍵字用法和異步的底層原理

目錄 C#異步編程一、異步編程基礎二、異步方法的工作原理三、代碼示例四、編譯后的底層實現五、總結 C#異步編程 一、異步編程基礎 異步編程是啥玩意兒 就是讓程序在干等著某些耗時操作&#xff08;比如等網絡響應、讀寫文件啥的&#xff09;的時候&#xff0c;能把線程騰出來…

安全教育知識競賽答題小程序怎么做

以下是制作安全教育知識競賽答題小程序的一般步驟&#xff1a; 一、準備階段 注冊小程序賬號&#xff1a;前往微信公眾平臺&#xff0c;注冊一個小程序賬號&#xff0c;主體類型可根據實際情況選擇個人或企業等&#xff0c;注冊成功后登錄獲取appid。 下載安裝開發工具&#x…

記錄待辦事項的便簽軟件有沒有推薦的?

在快節奏的現代生活中&#xff0c;我們每天都要處理大量的工作任務和生活瑣事&#xff0c;稍有不慎就可能遺漏重要事項。你是否經常遇到這樣的情況&#xff1a;明明記得有件事要做&#xff0c;卻怎么也想不起來是什么&#xff1b;或者手頭同時有好幾項任務&#xff0c;卻不知道…

實驗四 中斷實驗

一、實驗目的 掌握中斷服務程序的編寫。 二、實驗電路 三、實驗內容 1&#xff0e;實驗用PC機內部的中斷控制器8259A&#xff0c;中斷源用TPC-ZK實驗箱上的單脈沖電路&#xff0c;將單脈沖電路的輸出接中斷請求信號IRQ&#xff0c;每按一次單脈沖按鍵產生一次…

React 項目src文件結構

SCSS 組件庫 SCSS為預處理器 支持除原生CSS外的其他語句 別名路徑 在項目下的第一級目錄就加入craco.config.js文件并且修改packpage.js 中的部分 // 擴展webpage的配置const path require(path)module.exports {// exports配置webpack:{// 配置別名alias:{:path.resolve(__d…

Cursor入門教程-JetBrains過度向

Cursor使用筆記 **前置&#xff1a;**之前博主使用的是JetBrains的IDE&#xff0c;VSCode使用比較少&#xff0c;所以會盡量朝著JetBrains的使用習慣及樣式去調整。 一、設置語言為中文 如果剛上手Cursor&#xff0c;那么肯定對Cursor中的眾多選項配置項不熟悉&#xff0c;這…

Linux上位機開發實踐(SoC和MCU的差異)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 soc一般是指跑linux的芯片&#xff0c;而mcu默認是跑rtos的芯片&#xff0c;兩者在基本原理方面其實差異不大。只不過&#xff0c;前者由于性能的原…

離線導出和安裝Python庫

詳細介紹&#xff1a;離線導出和安裝Python庫 常用命令&#xff1a; 生成requirement.txt文件 pip freeze > requirement.txt離線批量下載庫 pip download -d packages -r requirement.txt離線批量安裝庫 pip install --no-index --find-links./ -r requirement.txt

基于Vue Node.js的電影售票網站的設計與實現(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 互聯網技術的成熟和普及&#xff0c;勢必會給人們的生活方式帶來不同程度的改變。越來越多的經營模式中都少不了線上運營&#xff0c;互聯網正強力推動著社會和經濟發展。國人對民族文化的自信和不同文化的包容&#xff0c;再加上電影行業的發展&#xff0c;如此繁榮吸引…

利用 Python 和 AI 技術創作獨特的圖像藝術作品

1. 項目目標 生成藝術作品&#xff1a;利用 AI 模型&#xff08;如 Stable Diffusion&#xff09;生成具有藝術風格的圖像。自定義風格&#xff1a;通過文本提示&#xff08;prompt&#xff09;控制圖像的藝術風格&#xff08;如賽博朋克、印象派、超現實主義等&#xff09;。…

XR技術賦能藝術展演|我的宇宙推動東方美學體驗化

本次廣州展覽現場引入我的宇宙XR體驗模塊&#xff0c;通過空間計算與動作捕捉技術&#xff0c;讓觀眾在潮玩藝術氛圍中體驗虛擬互動&#xff0c;打造“看得懂也玩得動”的展演新場景。 作為科技與文化融合的推動者&#xff0c;我的宇宙正在以“體驗科技”為媒介&#xff0c;為潮…

接口的集成測試步驟

一、集成測試是什么 ?接口的集成測試?是指在軟件開發過程中&#xff0c;將各個模塊或組件按照設計要求組合在一起&#xff0c;并測試它們之間的接口是否能夠正確交互和協同工作的過程。集成測試是軟件開發中的一個重要階段&#xff0c;通常在單元測試之后進行&#xff0c;目的…

上門服務 APP 30 億營收商業模式在烏干達的技術賦能與實踐

不久前&#xff0c;非洲烏干達出現黑人女技師提供上門足療服務的消息引發關注。據了解&#xff0c;當地一次40分鐘的上門按摩服務僅需約40元人民幣&#xff0c;價格僅為國內同類服務的十分之一。這一現象折射出全球健康服務行業正在經歷的數字化轉型浪潮。 國內領先的上門服務平…

go語言學習筆記:gin + gorm + mysql 用戶增刪改查案例入門

大家好&#xff0c;我是此林。 Golang 語言現在已經成為了編程的趨勢&#xff0c;畢竟是大廠背書嘛&#xff0c;Google 研發的。 目前很多云原生項目都是基于 go 來編寫的&#xff0c;比如&#xff1a; Kubernetes (K8s)? 容器編排系統&#xff0c; Docker? 容器化技術&…

探索亮數據Web Unlocker API:讓谷歌學術網頁科研數據 “觸手可及”

本文目錄 一、引言二、Web Unlocker API 功能亮點三、Web Unlocker API 實戰1.配置網頁解鎖器2.定位相關數據3.編寫代碼 四、Web Scraper API技術亮點 五、SERP API技術亮點 六、總結 一、引言 網頁數據宛如一座蘊藏著無限價值的寶庫&#xff0c;無論是企業洞察市場動態、制定…