Android JetPack架構篇,一個實戰專案帶你學懂JetPack
第五屆世界網際網路大會昨日開幕,來自76個國家的1500餘位嘉賓出席大會。騰訊公司董事會主席兼執行長馬化騰在大會開幕式演講中表示,全球產業都在進行數字化,在此期間機遇挑戰並存,產業網際網路機會巨大。
本篇來自 walker不抽菸 的投稿,給大家介紹一下 Android JetPack架構相關知識。一起來看看!希望大家喜歡。
walker不抽菸 的部落格地址:
https://blog.csdn.net/itismelzp
前言
本文翻譯自:Android Room with a View - Java,地址如下:
https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0
架構元件的目的是提供對應用程式體系結構的指導,併為諸如生命週期管理和資料持久化等常見任務提供開發庫。
架構元件幫你構造一個魯棒、易測試、可維護和少模板程式碼的應用。
架構元件是什麼?
為了介紹相關術語,這裡有簡短的介紹一下各架構元件以及它們之前如何協作。注意這個程式碼庫包含一部分架構元件,它們是:LiveData、ViewModel和Room。每個元件會在使用的時候做解釋。下圖是基本的架構形式。
Entity: 當註解的類,用於描述資料庫表。
SQLite database: SQLite資料庫。
DAO: 資料訪問物件。SQL查詢到方法的對映。
Room database: 在SQLite資料庫之上的資料庫層。
Repository: 資料倉庫,用於管理資料來源。
ViewModel: 提供資料給UI。是Repository與UI的連線中心。
你要構建什麼
這個Demo用於在Room中儲存words(單詞)列表,並顯示在RecyclerView中。這是個簡單的示例,但也足以為它來作為開發應用的模板。
Demo的功能:
獲取與儲存"單詞";
單詞顯示在MainActivity的RecyclerView中;
通過懸浮按鈕調起另一個activity,用於輸入單詞。
RoomWordSample架構預覽
下圖展示了應用的各個部分。除了SQLite database,其他部分都用在自己建立的類中封裝。
你會學到什麼
學會如何使用架構元件庫和生命週期庫設計和構建應用程式。
這裡有許多步驟去使用架構元件和推薦的框架。最重要的是學會模型建立的作用、理解各部分組合與資料流向。通過這個Demo,你不單只是簡單的複製和貼上本文的程式碼,還要理解其內部原理。
你需要掌握什麼
Android Studio 3.0或更高版本的使用。
一臺Android裝置或模擬器。
你必須熟悉Java程式設計,面向物件設計,Android開發基礎。尤其:
RecyclerView 及其介面卡adapters
SQLite資料庫及SQLite查詢語言
執行緒與AsyncTask
瞭解一些資料與UI分離的構架概念,如MVP、MVC
本Demo著重於Android架構元件,非主要程式碼可行自行復制與貼上。
Android Studio的優勢
建立應用
開啟Android Studio建立應用:
新建應用RoomWordSample,目標sdk為26+
不選include Kotlin support和include C++ support
下一步,選Phone & Tablet,minimum SDK選API 26
下一步,選擇Basic Activity
下一步,完成。
更新gradle檔案
新增元件庫到gradle。在Module:app的build.gradle中dependencies末尾加入:
// Room components
implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion"
// Lifecycle components
implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion"
中Project:RoomWordSample的build.gradle中加入版本資訊:
ext {
roomVersion = '1.1.1'
archLifecycleVersion = '1.1.1'
}
建立實體
本demo的資料是“單詞”,因此首先建立一個Word類,併為其建立建構函式與必要的get方法。這樣Room才可以例項化物件。
下面是Word類:
public class Word {
private String mWord;
public Word(@NonNull String word) {this.mWord = word;}
public String getWord(){return this.mWord;}
}
為了使Word類對Room庫有意義,我們需要為它加註解。註解用了將實體與資料庫相關聯,Room根據相應的註解資訊去生成對應的程式碼。
@Entity(tableName = "word_table") 每一個@Entity類代表資料庫中的一張表。tableName為生成表的表名。
@PrimaryKey 每個實體需要一個主鍵。
@NonNull 表示引數、欄位或返回值不能為null。
@ColumnInfo(name = "word") 指定與成員變數對應的列名。
為一個欄位需要是public的或提供get方法。
添加註解的Word類:
@Entity(tableName = "word_table")
public class Word {
@PrimaryKey
@NonNull
@ColumnInfo(name = "word")
private String mWord;
public Word(String word) {this.mWord = word;}
public String getWord(){return this.mWord;}
}
建立DAO(資料訪問物件)
什麼是DAO
DAO即資料訪問物件,你可以指定SQL查詢語句,並將它與方法關聯起來。編譯器會對常規SQL註解進行編譯檢查,如@Insert。
DAO物件必須是個介面或抽象類。
預設情況下,所有的查詢必須在單獨執行緒中執行。
Room將通過DAO物件去建立相應的介面。
DAO的寫法
DAO是程式碼的基礎,它用於提供word的增、刪、改、查。
建立一個名為WordDao的介面。
為WordDao新增@Dao註解
宣告一個插入方法void insert(Word word);
為上述方法新增@Insert註解,並且不需要為其提供SQL語句!(同樣的用法還有@Delete and @Update)
宣告方法void deleteAll();
這裡沒有方便的註解可以用於刪除多個實體,因此需要用@Query註解
還需要為@Query註解提供SQL語句@Query("DELETE FROM word_table")
建立方法List<Word> getAllWords();
為其添加註解與[email protected]("SELECT * from word_table ORDER BY word ASC")
下面是其完整的程式碼:
@Dao
public interface WordDao {
@Insert
void insert(Word word);
@Query("DELETE FROM word_table")
void deleteAll();
@Query("SELECT * from word_table ORDER BY word ASC")
List<Word> getAllWords();
}
LiveData類
當資料被改變後,通常你需要作一些操作,例如將更新的資料展示在UI上。這就意味著你必須去觀察這些資料,以便於當資料改變時你能做出反應。根據資料不同的儲存方式,這可能會很棘手。觀察貫串多個元件中資料的變化,你必須要編寫一個顯式、嚴格依賴的呼叫鏈。這使得測試和除錯變得非常困難。
LiveData是 lifecycle library 中,用於資料觀察的類,可用於解決上述難題。在你的方法中使用LiveData為返回值。這樣Room將會為你生成所有必須的程式碼,當資料庫更新時,自動去更新LiveData。
使用LiveData的目的是為了管理資料的更新。但是LiveData類並沒有提供公有的更新資料的方法。我們應當使用MutableLiveData,它有兩個公有方法(setValue(T)、postValue(T))用於儲存資料。通常,MutableLiveData是在ViewModel中使用,然後ViewModel只向觀察者暴露不可變的LiveData物件。
在WordDao中,改變getAllWords()方法的返回值:
@Query("SELECT * from word_table ORDER BY word ASC")
LiveData<List<Word>> getAllWords();
後面我們會在MainActivity的onCreate()方法中建立一個Observer物件,並覆蓋其onChanged()方法。當LiveData改變時,觀察者會被通知然後onChanged()會被回撥。這時你可以更新介面卡中的快取資料,然後在介面卡中更新UI。
新增Room資料庫
什麼是Room資料庫?
Room是在SQLite之上的資料庫層。Room用於處理我們曾經用SQLiteOpenHelper來處理任務。
Room通過DAO向資料庫傳送查詢
預設情況下,為了避免降低UI執行緒的效能,Room不允許在主執行緒中執行資料庫操作
Room提供了編譯時的SQL語句檢查
建立的Room類必須是抽象的,並且繼承RoomDatabase
通常,在整體應用中只需要一個Room資料庫例項,即單例。
實現Room資料庫
建立一個public abstract類WordRoomDatabase,並繼承RoomDatabase。即public abstract class WordRoomDatabase extends RoomDatabase {}
標註其為一個Room資料庫,@Database(entities = {Word.class}, version = 1),宣告其在資料庫中的實體,並指定版本號。實體可以宣告多個,宣告的實體將在資料庫中建立對應的表。
定義使用資料庫的DAO。給每一個@Dao提供get方法。public abstract WordDao wordDao();
完整程式碼如下:
@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {
public abstract WordDao wordDao();
}
使WordRoomDatabase作為單例。
private static volatile WordRoomDatabase INSTANCE;
static WordRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (WordRoomDatabase.class) {
if (INSTANCE == null) {
// Create database here
}
}
}
return INSTANCE;
}
例項化RoomDatabase物件:使用Room的databaseBuilder,從WordRoomDatabase類的應用上下文context中建立RoomDatabase物件,並將資料庫全名為"word_database"。
// Create database here
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WordRoomDatabase.class, "word_database")
.build();
下面是完整程式碼:
@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {
public abstract WordDao wordDao();
private static volatile WordRoomDatabase INSTANCE;
static WordRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (WordRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WordRoomDatabase.class, "word_database")
.build();
}
}
}
return INSTANCE;
}
}
建立Repository(資料倉庫)
什麼是Repository?
Repository是一個可訪問多資料來源的類。它並非構架元件庫中的一部分,但它是程式碼分離和體系結構的最佳實踐建議。Repository用於處理資料操作,它為應用提供資料訪問介面。
為什麼要使用Repository?
Repository管理查詢執行緒,並允許您使用多個後端。在最常見的示例中,Repository實現了決定是從網路獲取資料還是從本地快取中獲取結果的邏輯。
Repository的實現
建立一個公共類WordRepository
新增兩個成員變數
private WordDao mWordDao;
private LiveData<List<Word>> mAllWords;
新增一個建構函式,該建構函式獲取資料庫的控制代碼並初始化成員變數。
WordRepository(Application application) {
WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
mWordDao = db.wordDao();
mAllWords = mWordDao.getAllWords();
}
為getAllWords()新增一個包裝器。Room在單獨的執行緒上執行所有查詢。觀察到LiveData資料更改時,將通知觀察者。
LiveData<List<Word>> getAllWords() {
return mAllWords;
}
為insert()方法新增一個包裝器。使用AsyncTask來執行,確保其是在非UI執行緒中執行。
public void insert (Word word) {
new InsertAsyncTask(mWordDao).execute(word);
}
InsertAsyncTask的實現
private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {
private WordDao mAsyncTaskDao;
insertAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Word... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
下面是完整程式碼:
public class WordRepository {
private WordDao mWordDao;
private LiveData<List<Word>> mAllWords;
WordRepository(Application application) {
WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
mWordDao = db.wordDao();
mAllWords = mWordDao.getAllWords();
}
LiveData<List<Word>> getAllWords() {
return mAllWords;
}
public void insert (Word word) {
new insertAsyncTask(mWordDao).execute(word);
}
private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {
private WordDao mAsyncTaskDao;
insertAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Word... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
}
建立ViewModel
什麼是ViewModel?
ViewModel的作用是向UI提供資料,並儲存配置更改。ViewModel充當Repository 和UI之間的通訊中心。還可以使用ViewModel在fragments之間共享資料。ViewModel是 lifecycle library 庫的一部分。
為什麼使用ViewModel?
當配置被更改時,ViewModel以一種有生命週期感知的方式儲存應用的UI資料。將應用程式的UI資料與Activity和Fragment類分離,可以讓你更好地遵循單一責任原則:你的activities和fragments負責將資料繪製到螢幕上,而ViewModel則負責儲存和處理UI所需的所有資料。
在ViewModel中,對於UI將使用或顯示的可變資料,請使用LiveData。使用LiveData有幾個好處:
您可以在資料上放置一個觀察者(而不是輪詢更改),並且只在資料實際更改時更新UI。
Repository和UI由ViewModel完全分離。沒有來自ViewModel的資料庫呼叫,使得程式碼更易於測試。
ViewModel的實現
建立WordViewModel類,使其繼承AndroidViewModel。
public class WordViewModel extends AndroidViewModel {}
新增一個私有成員變數來儲存對儲存庫的引用。
private WordRepository mRepository;
新增一個私有LiveData成員變數來快取單詞列表。
private LiveData<List<Word>> mAllWords;
新增一個建構函式,該建構函式獲取對儲存庫的引用,並從儲存庫獲取單詞列表。
public WordViewModel (Application application) {
super(application);
mRepository = new WordRepository(application);
mAllWords = mRepository.getAllWords();
}
為所有單詞新增一個get方法。這完全隱藏了對UI的實現。
LiveData<List<Word>> getAllWords() { return mAllWords; }
建立一個呼叫Repository的insert()方法的包裝器insert()方法。這樣,insert()的實現對於UI就完全透明瞭。
public void insert(Word word) { mRepository.insert(word); }
下面是WordViewModel的實現:
public class WordViewModel extends AndroidViewModel {
private WordRepository mRepository;
private LiveData<List<Word>> mAllWords;
public WordViewModel (Application application) {
super(application);
mRepository = new WordRepository(application);
mAllWords = mRepository.getAllWords();
}
LiveData<List<Word>> getAllWords() { return mAllWords; }
public void insert(Word word) { mRepository.insert(word); }
}
警告:不要將context傳遞到ViewModel例項中。不要在ViewModel中儲存活動、片段或檢視例項或它們的context。
新增XML佈局
在value/styes.xml中新增列表項的樣式:
<!-- The default font for RecyclerView items is too small.
The margin is a simple delimiter between the words. -->
<style name="word_title">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">26dp</item>
<item name="android:textSize">24sp</item>
<item name="android:textStyle">bold</item>
<
相關推薦
Android JetPack架構篇,一個實戰專案帶你學懂JetPack
今日科技快訊
第五屆世界網際網路大會昨日開幕,來自76個國家的1500餘位嘉賓出席大會。騰訊公司董事會主席兼執行長馬化騰在大會開幕式演講中表示,全球產業都在進行數字化,在此期間機遇挑戰並存,產業網際網路機會巨大。
作者簡介
本篇來自 w
一個小專案帶你瞭解rest framework
這邊宣告一下,以下是參考官方文件來的。
新建專案
新建名為dimples的django專案
在其中建立一個名為astart的APP:
新建目錄
# 新建目錄
mkdir dimples
cd dimples
新建虛擬環境
virtualenv env
e
GitHub 熱點速覽 Vol.34:亞馬遜、微軟開源專案帶你學硬核技術
![](https://img2020.cnblogs.com/blog/759200/202008/759200-20200824230332585-1697508771.png)
作者:HelloGitHub-**小魚乾**
> 摘要:站在巨人的肩膀上才能看得更遠,本週上榜的 computerv
Android Studio compile project新增一個本地專案依賴包時,提示程式包不存在
問題情景
在一個專案裡,建了一個library專案和application專案,在application專案的build.gradle將library專案compile project進來,編譯的時候都正常,但是執行的時候,提示程式包不存在。
解決辦法
【Android開發】找樂,一個笑話App的制作過程記錄
override pbo rdm data root 恰恰 功能 sql htm
緣起
想做一個笑話App的原因是由於在知乎上看過一個帖子。做Android能夠有哪些數據能夠練手,裏面推薦了幾個數據開放平臺。在這些平臺中無一不是有公共的笑話接口,當時心
Android封裝jar包,把當前專案設定成module,封裝手機振動jar包給unity呼叫
Android封裝jar包或者把當前專案設定成module操作步驟都一樣,此處以手機振動為例,封裝jar包給Unity平臺使用,具體如下:
Android部分:
1.建立unity要呼叫的手機振動的類:PhoneVibrate
package com.lin.phonevibrate;
系統架構演化,改造ssm專案
階段一:單應用架構
完成
問題一:記憶體溢位java.lang.OutOfMemoryError 解決:對tomcat容器,可以在啟動時對jvm設定記憶體限度。對tomcat,可以在catalina.bat中新增:
set CATALINA_OPTS=-Xms128M -Xmx256M
set JAVA
Python 爬蟲速成教程,還有35個實戰專案送給你
前兩天,有個小夥伴問了黑馬哥這樣一個問題:Python可以爬到視訊網站上vip才能看到的視訊嗎?聽到這個問題,你是什麼反應?我當時的內心:開玩笑,還有Python爬不到的東西嗎?
今天黑馬哥就給大家總結了一些Python爬取各種東西的案例,讓你看看Python到底有多強大,而且黑馬哥還給大家準備
C# 串列埠操作系列(1) -- 入門篇,一個標準的,簡陋的串列埠例子。
我假設讀者已經瞭解了c#的語法,本文是針對剛打算解除串列埠程式設計的朋友閱讀的,作為串列埠程式設計的入門範例,也是我這個系列的基礎。
我們的開發環境假定為vs2005(雖然我在用vs2010,但避免有些網友用2005,不支援lambda,避免不相容,就用2005來做例子)
Android 取得 ListView中每一個Item專案的值
首先我們需要建立 ListView ,這裡假定我們已經建立好了並且使用SimpleAdapter設定好了adapter資料,看一下我們的adapter
ArrayList<HashMap<String, String>> list =
SpringMVC配置雙資料來源,一個java專案同時連線兩個資料庫
資料來源在配置檔案中的配置
[java] view
plain copy
print?
<pre name=“code”class=“java”><?xml version=“1.0” encoding=“UTF-8”?>
<beans xml
C# 串列埠操作系列(1) -- 入門篇,一個標準的,簡陋的串列埠例子
我假設讀者已經瞭解了c#的語法,本文是針對剛打算解除串列埠程式設計的朋友閱讀的,作為串列埠程式設計的入門範例,也是我這個系列的基礎。
我們的開發環境假定為vs2005(雖然我在用vs2010,但避免有些網友用2005,不支援lambda,避免不相容,就用2005來做例子
Android Studio安裝和第一個HelloAS專案
本篇將介紹Android Studio的安裝和執行的一個應用程式
本機系統環境:win7 64位
1.下載android-studio-bundle-145.3360264-windows,下載地址http://www.android-studio.org/
月薪30k+專案分紅,哥大教授帶你探索“區塊鏈+AI”,抓緊時間投簡歷吧!手慢無...
每週日,「區塊鏈大本營」人才快報與你不見不散!在這裡,可以第一時間瞭解區塊鏈的行業動態、技術風向與人才需求。
如果你是求職者,請將個人簡歷以Word文件形式(統一格式"求職+姓名+目標公司+應聘職位+手機號")發至郵箱;
如果你是招聘者,請將職位資
一篇文章帶你看懂AWS re:Invent 2018大會,揭祕Amazon Aurora
本文由雲+社群發表
| 本文作者: 劉峰,騰訊雲NewSQL資料庫產品負責人。曾職於聯想研究院,Teradata北京研發中心,從事資料庫相關工作8年。2017年加入騰訊資料庫產品中心,擔任NewSQL資料庫產品負責人。
雲資料庫與傳統資料庫的戰爭已打響,一個字概括就是“搶”。
如火如茶的 AWS re
一篇文章帶你看懂AWS re:Invent 2018大會,揭秘Amazon Aurora
2018年 保健 god 發揮 監控服務 insight 遊戲機 pci 雲計算 本文由雲+社區發表
| 本文作者: 劉峰,騰訊雲NewSQL數據庫產品負責人。曾職於聯想研究院,Teradata北京研發中心,從事數據庫相關工作8年。2017年加入騰訊數據庫產品中心,擔任Ne
實戰專案助你掌握JavaSE知識
目標模擬實現一個基於文字介面的《團隊人員排程軟體》
熟悉Java面向物件的高階特性,進一步掌握程式設計技巧和除錯技巧
主要涉及以下知識點:
類的繼承和多型物件的關聯static和final修飾符特殊類的使用異常處理
需求說明:模擬實現基於文字介面的《團隊人員排程軟體》。
該
一文帶你讀懂Cascade R-CNN,一個使你的檢測更加準確的網路
論文名稱:Cascade R-CNN: Delving into High Quality Object Detection
作者:Zhaowei Cai & Nuno Vasconcelos
論文連結:https://arxiv.org/abs/1712.0072
Android 去標題欄,Activity 滿屏那些你所不知道的 Theme Style
開篇前給大家介紹一個小技巧,就是PC插入U/硬碟載入太慢的解決辦法之一,xp/win7均適用:
①視窗+R鍵
②鍵入 services.msc 後回車
③找到 Shell Hardware Detec
架構師五分鐘帶你讀懂,Volatile的作用及原理
文章簡介
分析volatile的作用以及底層實現原理,這也是大公司喜歡問的問題
內容導航
vola