一
大概是在今年 5 6 月份的時候,我曾經(jīng)在公眾號中透漏過,今年打算再開發(fā)一個新的開源項(xiàng)目。那個時候基本思路其實(shí)已經(jīng)都想得差不多了,但是因?yàn)橥瑫r還要維護(hù) LitePal 和 PermissionX 這兩個開源項(xiàng)目,時不時還要寫些原創(chuàng)文章,所以我很不確定今年是否真的可以完成這個新開源項(xiàng)目。
而在今年的最后一個月,很高興地告訴大家,這個新項(xiàng)目我已經(jīng)基本完成了。雖然還有許多不足的地方,但是我相信目前已經(jīng)可以將第一個測試版本發(fā)布出來了。當(dāng)然第一個版本一定會存在不少 bug,我會根據(jù)大家的反饋不斷繼續(xù)完善代碼,這也將是另一個我會長期支持下去的開源項(xiàng)目。
那么接下來我們就具體聊一聊這個開源項(xiàng)目到底是什么吧。
其實(shí)做了 Android 開發(fā)這么多年,一直以來都有一個我認(rèn)為非常不人性化的地方,就是開發(fā)人員沒有辦法簡單直接地查看當(dāng)前應(yīng)用程序中的數(shù)據(jù)庫文件,這個問題導(dǎo)致 Android 數(shù)據(jù)庫的開發(fā)與調(diào)試工作一直都比較困難。
舉個例子,我們編寫了一段代碼去查詢數(shù)據(jù)庫當(dāng)中的某條數(shù)據(jù),但是卻沒能查出來。那么到底是因?yàn)椴樵冋Z句寫錯了?還是因?yàn)檫@條數(shù)據(jù)根本就不存在?要如何定位及解決這種問題是比較頭疼的,因?yàn)槲覀儫o法直觀地看到當(dāng)前數(shù)據(jù)庫中實(shí)際的數(shù)據(jù)。
那么過去大家都是如何解決的呢?
這個真的是八仙過海,各顯神通了。像我個人比較習(xí)慣的方式是直接用 SQL 命令查看,借助 adb shell 進(jìn)入控制臺,然后使用 sqlite3 命令打開某個數(shù)據(jù)庫文件,再接下來用傳統(tǒng)的 SQL 語句就能查看該數(shù)據(jù)庫當(dāng)中的數(shù)據(jù)了。只可惜這種方式自 Android 7.0 之后被禁止使用,主要還是考慮數(shù)據(jù)的安全性問題吧。
另外也有一些朋友可能會借助一些第三方的工具,比如說 SQLite Expert。這種工具是在電腦上用來查看數(shù)據(jù)庫文件的,因此需要先想辦法將手機(jī)中的數(shù)據(jù)庫文件導(dǎo)出到電腦上(這一步也并不容易,因?yàn)閮?nèi)置存儲空間的文件很難導(dǎo)出),然后再用 SQLite Expert 打開該文件即可查看其中的數(shù)據(jù)。
不管使用哪種方式,看上去都不是一件簡單的事情。有的時候我在開發(fā)過程中遇到一些數(shù)據(jù)庫的問題,一想到要用這么繁瑣的步驟才能查看到數(shù)據(jù)庫當(dāng)中的數(shù)據(jù),我寧愿換一種解決問題的思路。
Google 在過去一直沒有針對數(shù)據(jù)庫調(diào)試這方面提供了一個簡便的解決方案,這是我認(rèn)為非常不人性化的一點(diǎn)。
好消息是,最新的 Android Studio 4.1 當(dāng)中終于內(nèi)置了 Database Inspector 這個工具,在很大程度上解決了數(shù)據(jù)庫調(diào)試?yán)щy的問題。并且我認(rèn)為,Google 早就應(yīng)該提供這個工具了。
而我新開發(fā)的這個開源項(xiàng)目同樣也是為了解決這個問題。
二
最開始想到去做這樣一個開源項(xiàng)目,主要是受到 LeakCanary 的啟發(fā)。LeakCanary 相信很多朋友都用過,我們只需要將 LeakCanary 的庫集成到項(xiàng)目當(dāng)中,LeakCanary 就能自動檢測當(dāng)前項(xiàng)目的內(nèi)存泄漏情況,并通過可視化的界面將內(nèi)存泄漏問題展示給開發(fā)者。
然后我就想到,我是不是也可以開發(fā)一個開源庫,當(dāng)任何項(xiàng)目集成了這個開源庫后,就自動掃描當(dāng)前項(xiàng)目的內(nèi)置和外置存儲空間,把所有的數(shù)據(jù)庫文件都掃描出來,然后同樣提供一個可視化的界面以方便開發(fā)者隨時查看數(shù)據(jù)庫中的數(shù)據(jù)。
有了這個庫,當(dāng)我們在開發(fā)過程中再次遇到數(shù)據(jù)庫問題時,直接通過可視化界面查看一下數(shù)據(jù)庫當(dāng)中真實(shí)的數(shù)據(jù)是什么樣的,哪里出了問題就一目了然了。
雖然聽上去和 Database Inspector 的功能有點(diǎn)重疊,但其實(shí)它們的目標(biāo)場景是完全不同的。Database Inspector 需要手機(jī)連到電腦上,然后在 Android Studio 里查看數(shù)據(jù)庫當(dāng)中的數(shù)據(jù)。而我開發(fā)的這個開源庫不需要連接電腦,只需在手機(jī)上即可查看(有點(diǎn)類似于 Profiler 和 LeakCanary 之間的關(guān)系)。
我給這個開源庫起名為:Glance,意為一瞥的意思。我希望能讓開發(fā)者們通過快速一瞥即可定位開發(fā)當(dāng)中遇到的數(shù)據(jù)庫問題,所以起了這樣一個名字。
確定了項(xiàng)目名和設(shè)計(jì)思路之后,接下來我就開始動手開發(fā)了。事實(shí)上,Glance 的開發(fā)過程一路都比較順利,可能主要是因?yàn)橹伴_發(fā)過 LitePal,所以在數(shù)據(jù)庫方面積累了很多經(jīng)驗(yàn)。
并且,我對 Glance 的定位不僅僅只是一個協(xié)助查看數(shù)據(jù)庫內(nèi)容的工具,同時也是一個非常好的學(xué)習(xí)項(xiàng)目。在編寫 Glance 的時候,我特意使用了許多 Google 目前最推薦使用的各項(xiàng)新技術(shù),包括 Kotlin、協(xié)程、Paging3、App Startup、MVVM 等等等等,基本都是按照最標(biāo)準(zhǔn)的項(xiàng)目開發(fā)規(guī)范去實(shí)現(xiàn)的。所以,學(xué)習(xí)這個項(xiàng)目的源碼相信也會對你的開發(fā)水平有非常大的幫助。
我大概是從 8 月中旬的時候開始著手編寫的這個項(xiàng)目,到 11 月份的時候基本就將所有主要的功能都開發(fā)完成了。期間還進(jìn)行了一輪小范圍的內(nèi)部測試,幾位熱心群友幫我發(fā)現(xiàn)了好幾個頗為嚴(yán)重的 bug,我又對此一一進(jìn)行了修復(fù)。
那么現(xiàn)在,我認(rèn)為這可以算是一個相對比較穩(wěn)定的版本了。但是由于畢竟是全新的開源庫,我還不敢直接發(fā)布 1.0.0 版本,因此這次發(fā)布的是 1.0.0-alpha01 版本。大家如果在使用的過程中發(fā)現(xiàn)了任何問題,很正常,反饋給我即可,我會盡快進(jìn)行修復(fù)。
三
好了,接下來就向大家介紹 Glance 的具體用法吧。其實(shí)真的非常非常簡單,只需要使用如下語句將 Glance 引入到你的項(xiàng)目當(dāng)中:
dependencies {? ? debugImplementation 'com.glance.guolindev:glance:1.0.0-alpha01'}復(fù)制代碼
然后就結(jié)束了。
沒錯,就是這么簡單,Glance 沒有提供任何對外的 API,所以也不需要你進(jìn)行什么代碼對接操作,只要將依賴庫引入到你的項(xiàng)目當(dāng)中,就算是對接完成了。
注意上述的引用語句中我們使用的關(guān)鍵字是 debugImplementation,這個關(guān)鍵字相信大家用的比較少,通常我們使用的都是 implementation 關(guān)鍵字。那么 debugImplementation 是什么意思呢?它表示只有在你的項(xiàng)目是 debug 版的時候,才會將 Glance 引入到你的項(xiàng)目當(dāng)中,而 release 版是不會包含 Glance 庫的。
這是一種最為安全的做法,因?yàn)槿绻?release 版中引入了 Glance 庫,相當(dāng)于給你的應(yīng)用程序留了個后門,是有可能引起數(shù)據(jù)庫安全問題的。
接下來就像平常那樣運(yùn)行你的程序就可以了,你會發(fā)現(xiàn),你的手機(jī)桌面上將會多出一個 Glance 的圖片,如下圖所示。
這個圖標(biāo)就是引入了 Glance 庫之后自動生成的,點(diǎn)擊該圖標(biāo)即可打開 Glance 的可視化界面,如下圖所示。
在這里,Glance 會自動開始掃描當(dāng)前應(yīng)用程序的內(nèi)置和外置存儲空間,將所有的數(shù)據(jù)庫文檔全部搜索到,并一一列出。
比如上圖中的 demo1.db 就是我當(dāng)前項(xiàng)目工程中的一個數(shù)據(jù)庫文件,internal storage 表示它是存放在內(nèi)置存儲空間下的。
點(diǎn)擊 demo1.db,即可打開這個數(shù)據(jù)庫文件,并將該數(shù)據(jù)庫中的所有表羅列出來,如下圖所示。
當(dāng)然這里列出的表并不全部都是由我們自己創(chuàng)建的,比如 android_metadata、sqlite_sequence 這些表就是自動生成的。但 Glance 并不會對此進(jìn)行區(qū)分,而是會把它們?nèi)苛_列出來。
接下來點(diǎn)擊 magazine 表,我們即可查看表中的數(shù)據(jù)。橫向滾動可以查看所有的列,縱向滾動可以查看所有的行,如下圖所示。
這里對表中的數(shù)據(jù)進(jìn)行加載使用了分頁技術(shù),所以即使你的表中有上百萬條數(shù)據(jù),也會非??焖俚丶虞d出來。而 Glance 的分頁技術(shù)是使用 Paging3 實(shí)現(xiàn)的,對 Paging3 感興趣的朋友可以參考參考這部分的源碼。
到這里為止,我們就可以非常方便地隨時查看當(dāng)前應(yīng)用程序數(shù)據(jù)庫中的數(shù)據(jù)了。相比于之前還要想辦法導(dǎo)出數(shù)據(jù)庫文件,發(fā)送到電腦上,再借助第三方工具進(jìn)行查看,是不是簡單了千百倍?
即使相比于 Database Inspector,我認(rèn)為 Glance 也是有很大優(yōu)勢的,畢竟你不需要借助電腦,也不需要打開 Android Studio 才能查看。
另外,假如你的數(shù)據(jù)庫文件發(fā)生了變化,Glance 也可以迅速地感知到。比如我們向當(dāng)前應(yīng)用程序的外置存儲空間當(dāng)中添加一個新的數(shù)據(jù)庫文件,如下圖所示。
可以看到,當(dāng)回到 Glance 的可視化界面之后,迅速就能發(fā)現(xiàn)新增了一個 demo2.db,external storage 表示它是存放在空間存儲空間下的。
然后我們就可以立刻查看 demo2.db 當(dāng)中的全部數(shù)據(jù)了。
那么關(guān)于 Glance 的用法介紹到這里大概就差不多了。因?yàn)楫吘顾闹饕δ芫褪且粋€輔助型的工具,并不是什么需要去開發(fā)和對接的庫,所以整體用法是非常簡單的。
接下來我想聊一聊 Glance 的限制,至少在目前第一個版本中,這些限制是需要提醒大家的。
首先,Glance 只提供對數(shù)據(jù)庫進(jìn)行查看的功能,并不提供修改和刪除的功能。當(dāng)然之所以不支持修改和刪除,并不是因?yàn)槭裁雌渌厥獾脑?,純粹只是因?yàn)槲覜]時間。為了能趕在今年內(nèi)上線第一個版本,我選擇了只開發(fā)了最核心的查看功能。
在接下來的版本更新當(dāng)中,修改和刪除數(shù)據(jù)庫的功能會有極大的概率被加入進(jìn)去。
第二,Glance 只支持使用 AndroidX 架構(gòu)的項(xiàng)目,并且未來也只會支持 AndroidX 架構(gòu)。如果你的項(xiàng)目還在使用 Support Library 架構(gòu),那么很遺憾,你將無法使用 Glance。
關(guān)于這個限制我其實(shí)思考了很久,因?yàn)楸旧聿榭磾?shù)據(jù)庫功能和 AndroidX 架構(gòu)一點(diǎn)關(guān)系都沒有。但是我在 Glance 當(dāng)中使用了大量最新的 Google 技術(shù),如協(xié)程、Paging3、App Startup 等等,這些新技術(shù)都是只支持 AndroidX 架構(gòu)的。那么到底是為了更好的兼容性而不使用這些新技術(shù),還是為了讓 Glance 更具有學(xué)習(xí)意義而使用這些新技術(shù),我最終選擇了后者。
另外我相信,AndroidX 終將是趨勢,即使現(xiàn)在還在使用 Support Library 的項(xiàng)目,在不久的將來也必然會轉(zhuǎn)換到 AndroidX 架構(gòu)上,所以對此我并不是很擔(dān)心。
四
好了,關(guān)于 Glance 第一個版本的所有介紹就到這里。也很高興我將今年定下的最后一個小目標(biāo)也實(shí)現(xiàn)了,這一年真的可以說是收獲滿滿。
最后附上 Glance 的開源庫地址,想學(xué)習(xí)源碼的朋友不要錯過哦。另外也請幫我隨手點(diǎn)個 star,謝謝大家。
如果想要學(xué)習(xí) Kotlin 和最新的 Android 知識,可以參考我的新書《第一行代碼 第 3 版》,點(diǎn)擊此處查看詳情。