Android -第二十一次技術總結

?一、activity與Fragment的通信有哪些?

????????使用接口進行通信的邏輯與代碼示例

????????使用接口通信的核心是解耦,通過定義一個接口作為通信契約,讓 Fragment 不依賴于具體的 Activity 類型。

1. 定義通信接口(在 Fragment 內)

首先,在 Fragment 內部定義一個公共接口。這個接口就像一份協議,規定了 Fragment 想要傳遞給 Activity 的信息類型和方法。

// MyFragment.java
public class MyFragment extends Fragment {// 定義通信接口public interface OnMessageSendListener {void onMessageSent(String message);}private OnMessageSendListener listener;// ... 其他 Fragment 生命周期方法@Overridepublic void onAttach(@NonNull Context context) {super.onAttach(context);// 檢查宿主 Activity 是否實現了接口if (context instanceof OnMessageSendListener) {listener = (OnMessageSendListener) context;} else {// 如果沒有實現,拋出異常,提醒開發者throw new RuntimeException(context.toString() + " must implement OnMessageSendListener");}}// Fragment 內部觸發事件的方法private void triggerCommunication() {if (listener != null) {// 調用接口方法,傳遞數據listener.onMessageSent("Hello from Fragment!");}}
}
2. Activity 實現接口并處理數據

然后,你的 Activity 必須實現這個接口。這就像在說:“好的,我愿意遵守這份契約,并且知道如何處理來自 Fragment 的數據。”

// MyActivity.java
public class MyActivity extends AppCompatActivity implements MyFragment.OnMessageSendListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 假設這里將 MyFragment 添加到了 ActivitygetSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new MyFragment()).commit();}// 實現接口中定義的方法@Overridepublic void onMessageSent(String message) {// 在 Activity 中處理從 Fragment 接收到的數據Toast.makeText(this, "收到來自 Fragment 的消息: " + message, Toast.LENGTH_SHORT).show();}
}

邏輯總結: 這個過程非常清晰:Fragment 不關心它的宿主是誰,它只知道需要一個實現了 OnMessageSendListener 接口的對象。只要 Activity 遵守了這個約定,通信就能安全地進行。這種方式徹底解耦了 Fragment 和 Activity,提高了 Fragment 的可復用性。

????????使用 ViewModel 進行通信的邏輯與代碼示例

使用 ViewModel 進行通信的核心是數據驅動。Activity 和 Fragment 不再直接交互,而是通過一個共享的 ViewModel 實例作為數據中心,來同步數據。

1. 創建共享的 ViewModel

首先,創建一個繼承自 ViewModel 的類,并用 MutableLiveData 來封裝你需要共享的數據。

// SharedViewModel.java
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;public class SharedViewModel extends ViewModel {// MutableLiveData 用于在 ViewModel 內部修改數據private final MutableLiveData<String> selectedItem = new MutableLiveData<>();// 提供一個公開方法,供外部調用以更新數據public void selectItem(String item) {selectedItem.setValue(item);}// 提供一個不可變的 LiveData 實例供外部觀察public LiveData<String> getSelectedItem() {return selectedItem;}
}
2. Fragment A(數據發送方)

在發送數據的 Fragment 中,通過其宿主 Activity 的范圍(by activityViewModels()ViewModelProvider)獲取 ViewModel 的實例,然后調用其方法來更新數據。

// FragmentA.java
public class FragmentA extends Fragment {// 獲取共享的 ViewModel 實例private SharedViewModel sharedViewModel;@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 使用 ViewModelProvider 獲取同一個實例sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_a, container, false);Button button = view.findViewById(R.id.send_button);button.setOnClickListener(v -> {// 當按鈕被點擊時,更新 ViewModel 中的數據sharedViewModel.selectItem("Data from Fragment A");});return view;}
}
3. Fragment B(數據接收方)

在接收數據的 Fragment 中,也通過同樣的方式獲取 ViewModel 的實例,然后觀察observeLiveData 的變化。

// FragmentB.java
public class FragmentB extends Fragment {private SharedViewModel sharedViewModel;private TextView textView;@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_b, container, false);textView = view.findViewById(R.id.received_data_text_view);// 觀察 ViewModel 中的數據變化sharedViewModel.getSelectedItem().observe(getViewLifecycleOwner(), item -> {// 當數據發生變化時,更新 UItextView.setText(item);});return view;}
}

????????邏輯總結: 這個過程的核心是數據流。Fragment A 只負責更新 ViewModel 中的數據,Fragment B 和 Activity 只負責觀察這些數據。它們之間沒有直接引用。這種方式不僅徹底解耦了組件,還利用了 LiveData 的生命周期感知特性,自動處理了數據在屏幕旋轉等配置變化時的持久化,有效防止了內存泄漏。它代表了現代 Android 開發中組件通信的最新趨勢和最佳實踐。

二、String類與List,Set,Map類

StringStringBuilderStringBuffer 三者作用、意義和區別。

????????String 是最基礎的字符串類,但它最大的特點是不可變性。這意味著一旦創建,它的值就無法改變。任何對 String 的修改操作,比如拼接,都會在內存中創建一個全新的 String 對象,而舊的對象則會被回收。因此,String 適用于那些不需要頻繁修改的場景,它的不可變性也保證了線程安全,使其成為一個可靠的數據類型。然而,如果需要進行大量的字符串操作,尤其是在循環中,頻繁創建新對象的開銷會嚴重影響程序性能。

????????為了解決 String 的性能問題,Java 引入了 StringBuilderStringBuffer。這兩者都屬于可變的字符串,它們在內部維護一個動態的字符數組,可以直接在原有對象上進行修改,而無需創建新的對象。這使得它們在進行字符串拼接、插入等操作時,效率遠高于 String。其中,StringBuilder 的性能最高,因為它沒有線程同步(synchronized)的開銷,這使得它在單線程環境下成為處理字符串修改的首選工具。

????????StringBufferStringBuilder 的功能幾乎完全相同,但關鍵區別在于線程安全性StringBuffer 的所有方法都是線程同步的,這意味著在多線程環境中,它可以確保同一時間只有一個線程能訪問它,從而避免了數據不一致的問題。然而,這種同步機制會帶來額外的性能開銷,所以在單線程環境下,使用 StringBuffer 是不必要的,會比 StringBuilder 慢。因此,在選擇時,應根據項目的具體需求來決定:單線程用 StringBuilder,多線程用 StringBuffer,而 String 則用于處理不需要修改的簡單字符串。

ListSetMap 是 Java 集合框架中最基礎也是最重要的三種接口,它們都用于存儲對象,但各自有獨特的存儲方式、行為和適用場景。理解它們的區別,是高效編程的關鍵。

List(列表)

????????List 是一種有序、可重復的集合。你可以把它想象成一個數組,每個元素都有一個對應的索引,因此你可以通過索引來精確地訪問、添加或刪除元素。由于它允許重復元素,你可以多次添加同一個對象。在實際應用中,當你需要一個元素的順序很重要,或者需要存儲重復數據時,List 是你的首選。常見的實現類有 ArrayListLinkedList,前者基于數組,隨機訪問速度快;后者基于鏈表,插入和刪除操作更高效。

Set(集合

????????Set 是一種無序、不可重復的集合。它的行為更像一個數學意義上的集合,所有元素都是唯一的。當你試圖向一個 Set 中添加一個已經存在的元素時,添加操作會失敗。正因為這種獨一無二的特性,Set 非常適合用來去重。例如,如果你需要統計一篇文章中不重復的單詞數量,Set 就能輕松勝任。常見的實現類有 HashSetTreeSetHashSet 提供了最快的查找速度,而 TreeSet 則會保持元素的排序。

Map(映射)

????????Map 是一種鍵值對的集合。它存儲的不是單個元素,而是由“鍵(Key)”和“值(Value)”組成的配對。每個鍵都是唯一的,并且與一個值相關聯。你可以通過鍵來快速查找、更新或刪除對應的值,就像查字典一樣。Map 非常適合用于存儲需要通過某種唯一標識來檢索的數據,比如一個用戶的 ID 對應其個人信息,或者一個學生的學號對應其成績。常見的實現類有 HashMapTreeMapHashMap 提供了無序的快速存取,而 TreeMap 則會按鍵的自然順序進行排序。

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

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

相關文章

【算法】78.子集--通俗講解

通俗易懂講解“子集”算法題目 一、題目是啥?一句話說清 給你一個不含重復元素的整數數組,返回所有可能的子集(包括空集和它本身)。 示例: 輸入:nums = [1,2,3] 輸出:[[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]] 二、解題核心 使用回溯法(遞歸)或位運算來…

Cherrystudio的搭建和使用

1、下載和安裝 Cherry Studio 官方網站 - 全能的 AI 助手 2、配置LLM 3、聊天助手 3.1 添加和編輯助手 3.2 選擇LLM 3.3 對話聊天 4、配置MCP 4.1 安裝MCP執行插件 4.2 安裝 node和npm Node.js — Download Node.js npm -v 10.9.3 node -v v22…

基于Matlab結合膚色檢測與卷積神經網絡的人臉識別方法研究

近年來&#xff0c;隨著人工智能與計算機視覺技術的發展&#xff0c;人臉識別在人機交互、安防監控、身份認證等領域得到了廣泛應用。本文提出了一種基于 MATLAB 平臺&#xff0c;結合 膚色檢測與卷積神經網絡&#xff08;CNN&#xff09; 的人臉識別方法。該方法首先利用膚色模…

在八月點燃AI智慧之火:CSDN創作之星挑戰賽開啟靈感盛宴

在八月點燃AI智慧之火&#xff1a;CSDN創作之星挑戰賽開啟靈感盛宴八月驕陽似火&#xff0c;智能時代的技術熱情同樣熾熱。在這個充滿創新活力的季節&#xff0c;「AIcoding八月創作之星挑戰賽」正式拉開帷幕&#xff0c;為CSDN的創作者們打造一個展示才華、碰撞靈感的專業舞臺…

解密 Vue 3 shallowRef:淺層響應式 vs 深度響應式的性能對決

&#x1f4d6; 概述 shallowRef() 是 Vue 3 中的一個組合式 API 函數&#xff0c;用于創建淺層響應式引用。與 ref() 不同&#xff0c;shallowRef() 只在其 .value 被直接替換時觸發響應式更新&#xff0c;不會深度監聽對象內部屬性的變化。 &#x1f3af; 基本概念 什么是 sh…

Linux進程間通信(IPC)深入解析

Linux進程間通信&#xff08;IPC&#xff09;深入解析 1 概述 Linux 進程間通信 (Inter-Process Communication, IPC) 是不同進程之間交換數據與同步操作的機制。現代 Linux 內核提供了多種 IPC 方式&#xff0c;從傳統的管道和 System V IPC 到現代的套接字和 D-Bus&#xff0…

TensorFlow-GPU版本安裝

前言&#xff1a; &#xff08;1&#xff09;因項目需求&#xff0c;需要安裝TensorFlow-GPU版本&#xff0c;故本文在此記錄安裝過程。 &#xff08;2&#xff09;有注釋&#xff0c;優先看注釋 &#xff08;3&#xff09;本文所使用的GPU為NVIDIA GeForce RTX 5080 Laptop GP…

Elasticsearch 索引字段刪除,除了 Reindex 重建索引還有沒有別的解決方案?

unsetunset1、問題來源unsetunset在生產環境維護 Elasticsearch 集群的過程中&#xff0c;經常會遇到這樣的場景&#xff1a;業務需求變更導致某些字段不再使用&#xff0c;或者早期設計時添加了一些冗余字段&#xff0c;現在需要清理掉。最近球友在公司的一個項目中就遇到了這…

Ubuntu虛擬機磁盤空間擴展指南

這是一份詳細且易于理解的 Ubuntu 虛擬機磁盤空間擴展指南。本指南涵蓋了兩種主流虛擬機軟件&#xff08;VirtualBox 和 VMware&#xff09;的操作步驟&#xff0c;并分為 “擴展虛擬磁盤” 和 “在 Ubuntu 內部分配新空間” 兩大部分。重要提示&#xff1a;在進行任何磁盤操作…

教程1:用vscode->ptvsd-創建和調試一個UI(python)-轉載官方翻譯(有修正)

vscode用python開發maya聯動調試設置 3dsMax Python開發環境搭建 3文聯動之debugpy調試max‘python. 3文聯動之socket插槽注入max‘python 本教程是max主動接收創建代碼的方式&#xff08;預先運行界面&#xff0c;通過按鈕主動讀取py腳本&#xff0c;執行斷點&#xff09;&…

龍迅#LT7621GX適用于兩路HDMI2.1/DP1.4A轉HDMI2.1混切應用,分辨率高達8K60HZ!

1. 描述LT7621GX是一款高性能兩路HDMI2.1/DP1.4轉HDMI2.1混合開關芯片&#xff0c;用于顯示應用。 HDCP RX作為HDCP中繼器的上游&#xff0c;可以與其他芯片的HDCP TX配合&#xff0c;實現中繼器功能。 對于HDMI2.1輸入&#xff0c;LT7621GX可以配置為3/4通道。自適應均衡使其適…

【Ruoyi 解密 - 12. JDK17的新特性】------ 從Java 8 到 Java 17:向Scala看齊的“簡潔革命”,同宗JVM下的效率狂飆

從Java 8到Java 17&#xff1a;抄作業Scala&#xff1f;JVM同宗下的Ruoyi開發效率狂飆&#xff01; 上一篇我們聊到JDK 17對Python的柔性借鑒&#xff0c;可深入用下來才發現——這哪夠&#xff01;對Ruoyi開發者來說&#xff0c;JDK 17真正的“王炸”&#xff0c;是把同根JVM的…

大模型 “輕量化” 之戰:從千億參數到端側部署,AI 如何走進消費電子?

一、大模型 “輕量化” 的行業背景在 AI 技術蓬勃發展的當下&#xff0c;大模型已然成為行業焦點。從 GPT-4 突破萬億級參數量&#xff0c;到 DeepSeek-R1 邁向千億參數規模&#xff0c;大模型的參數擴張趨勢顯著。然而&#xff0c;這種規模的增長也帶來了諸多挑戰。以 GPT-4 為…

香港電訊與Microsoft香港推出新世代“Teams Phone” 解決方案

香港電訊成為香港首家提供 “Microsoft Operator Connect”的本地電訊營運商1 香港電訊&#xff08;股份代號&#xff1a;6823&#xff09;【香港 ? 2025年2月11日】 – 香港電訊宣布與 Microsoft 香港合作推出 “Operator Connect”&#xff0c;成為全港首家為企業客戶提供全…

PlantUML描述《分析模式》第3章觀察和測量(2)

lantUML描述《分析模式》第2章“當責”&#xff08;1&#xff09; PlantUML描述《分析模式》第2章“當責”&#xff08;2&#xff09; PlantUML描述《分析模式》第3章觀察和測量&#xff08;1&#xff09; 原圖3.8 EA繪制 圖3.8 遞歸關系用于記錄證據和評估。 PlantUML sta…

輪廓周長,面積,外界圓,外界矩形近似輪廓和模板匹配和argparse模塊實現代碼參數的動態配置

目錄 一.輪廓操作 1.輪廓特征的引入與篩選 2.輪廓排序和精準定位 3.外接圓與外接矩形的計算與繪制 二.輪廓近似 1.輪廓近似的基本概念 2.輪廓近似的實現方法和核心步驟 3. 近似精度參數的設定邏輯 4.輪廓定位方法 三.模板匹配 1.模板匹配技術原理與實現流程 2.技術要…

【第三方網站測評:會話管理漏洞的測試與加固】

會話管理是Web應用安全的用于在無狀態的HTTP協議上維持用戶狀態。漏洞主要源于會話令牌(Session Token)的生成、傳輸、驗證和銷毀過程中的缺陷。攻擊者利用這些缺陷可劫持用戶會話,未經授權訪問敏感數據或執行特權操作,屬于OWASP TOP 10中身份驗證失效的高頻風險。 會話管…

理想汽車智駕方案介紹專題 3 MoE+Sparse Attention 高效結構解析

一、前言 【理想汽車智駕方案介紹專題 -1】端到端VLM 方案介紹 【理想汽車智駕方案介紹專題 -2】MindVLA 方案詳解 在上述兩篇系列帖子中&#xff0c;筆者已對理想汽車 VLM 和 VLA 方案的框架進行了全面介紹&#xff0c;但對于其中的前沿技術僅做了初步探討&#xff0c;未進…

如何將yolo訓練圖像數據庫的某個分類的圖像取出來

COCO 數據集 - Ultralytics YOLO 文檔 比如我只想從數據集中取手機的圖像&#xff0c;來用于我的訓練&#xff0c;懶得自己一張一張標注&#xff0c;方法如下 # -*- coding: utf-8 -*- import json import os import shutil from pathlib import Path from tqdm import tqdm i…

【WPF】WPF 自定義控件實戰:從零打造一個可復用的 StatusIconTextButton (含避坑指南)

&#x1f527; WPF 自定義控件實戰&#xff1a;從零打造一個可復用的 StatusIconTextButton&#xff08;含避坑指南&#xff09;發布于&#xff1a;2025年8月29日 標簽&#xff1a;WPF、C#、自定義控件、MVVM、Generic.xaml、屬性綁定、TemplateBinding&#x1f4cc; 引言 在 W…