當前位置:首頁 » 數據倉庫 » android資料庫優化
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

android資料庫優化

發布時間: 2023-02-11 04:33:27

A. 什麼是android系統,android的發展以及android的平台架構和特性

Android平台採用了整合的策略思想,包括底層Linux操作系統、中間層的中間件和上層的Java應用程序。下面我把Android的特性及其架構體系結構總結一下。

一、Android的平台特性

Android平台有如下特性:

1. 應用程序框架支持組件的重用與替換。

這樣我們可以把系統中不喜歡的應用程序刪除,安裝我們喜歡的應用程序。

2. Dalvik虛擬機專門為移動設備進行了優化。

Android應用程序將由Java編寫、編譯的類文件通過DX工具轉換成一種後綴名為.dex的文件來執行。Dalvik虛擬機是基於寄存器的,相對於Java虛擬機速度要快很多。

3. 內部集成瀏覽器基於開源的WebKit引擎。

有了內置的瀏覽器,這將意味著WAP應用的時代即將結束,真正的移動互聯網時代已經來臨,手機就是一台「小電腦」,可以在網上隨意遨遊。

4. 優化的圖形庫包括2D和3D圖形庫,3D圖形庫基於OpenGL ES 1.0。

強大的圖形庫給游戲開發帶來福音。在3G最為重要的的應用莫過於手機上網和手機游戲。

5. sqlite用作結構化的數據存儲

6. 多媒體支持包括常見的音頻、視頻和靜態印象文件格式

如MPEG4、H.264、MP3、AAC、AMR、JGP、PNG、GIF。

7. GSM電話(依賴於硬體)。

8. 藍牙(Bluetooth)、EDGE、3G、WiFi(依賴於硬體)。

9. 照相機、GPS、指南針和加速度計(依賴於硬體)。

10. 豐富的開發環境包括設備模擬器、調試工具、內存及性能分析圖表和Eclipse集成的開發環境插件。

Google提供了Android開發包SDK,其中包含了大量的類庫和開發工具,並且針對Eclipse的可視化開發插件ADT。

二、Android平台架構

從上圖我們可以看出,Android操作系統的體系結構可分為4層,由上到下依次是應用程序、應用程序框架、核心類庫和Linux內核,其中第三層還包括Android運行時的環境。下面分別來講解各個部分。

1. 程序應用

Android
連同一個核心應用程序包一起發布,該應用程序包包括E-mail客戶端、SMS短消息程序、日歷、地圖、瀏覽器、聯系人管理程序等。所有的應用程序都是用Java編寫的。

2. 應用程序框架

開發者完全可以訪問核心應用程序所使用的API框架。該應用程序框架架構用來簡化組件軟體的重用,任何一個應用程序都可以發布它的功能塊並且任何其他的應用程序都可以使用其所發布的功能塊(不過得遵循框架的安全性限制)。該應用程序重用機制使得組件可以被用戶替換。

以下所有的應用程序都由一系列的服務和系統組成,包括:

1)一個可擴展的視圖(Views)可以用來創建應用程序,包括列表(lists)、網路(grids)、文本框(text
boxes)、按鈕(buttons),甚至是一個可嵌入的Web瀏覽器。

2)內容管理器(Content Providers)使得應用程序可以訪問另一個應用程序的數據(如聯系人資料庫),或者共享它們自己的數據。

3)一個資源管理器(Resource Manager)提供非代碼資源的訪問,如本地字元串、圖形和分層文件(layout files)。

4)一個通知管理器(Notification Manager)使得應用程序可以在狀態欄中顯示客戶通知信息。

5)一個活動類管理器(Activity Manager)用來管理應用程序生命周期並提供常用的導航回退功能。

3. Android程序庫

Android包括一個被Android系統中各種不同組件所使用的C/C++集庫。該庫通過Android應用程序框架為開發者提供服務。

以下是一些主要的核心庫:

1)系統C庫:一個從BSD繼承來的標准C系統函數庫(libc),專門為基於Embedded Linux的設備定製。

2)媒體庫:基於PacketVideo
OpenCORE;該庫支持錄放,並且可以錄制許多流行的音頻視頻格式,還有靜態映像文件包括MPEG4、H.264、MP3、AAC、JPG、PNG。

3)Surface Manager:對顯示子系統的管理,並且為多個應用程序提供2D和3D圖層的無縫融合。

4)LibWebCore:一個最新的Web瀏覽器引擎,用來支持Android瀏覽器和一個可嵌入的Web視圖。

5)SGL:一個內置的2D圖形引擎。

6)3D libraries:基於OpenGL ES 1.0 APIs實現;該庫可以使用硬體3D加速(如果可用)或者使用高度優化的3D軟加速。

7)FreeType:點陣圖(bitmap)和向量(vector)字體顯示。

8)SQLite:一個對於所以應用程序可用、功能強勁的輕型關系型資料庫引擎。

4. Android運行庫

Android包括了一個核心庫,該核心庫提供了Java編程語言核心庫的大多數功能。

每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。Dalvik是針對同時高效地運行多個VMs實現的。Dalvik虛擬機執行.dex的Dalvik可執行文件,該格式文件針對最小內存使用做了優化。該虛擬機是基於寄存器的,所有的類都是經由Java匯編器編譯,然後通過SDK中的DX工具轉化成.dex格式由虛擬機執行。

Dalvik虛擬機依賴於Linux的一些功能,比如線程機制和底層內存管理機制。

5. Linux內核

Android的核心系統服務依賴於Linux內核,如安全性、內存管理、進程管理、網路協議棧和驅動模型。Linux內核也同時作為硬體和軟體棧之間的硬體抽象層。

B. android怎麼把checkbox狀態設置為選中狀態

android:checked="true"就是設置checkbox狀態為選中狀態。

C. Android Green插入10萬條數據OOM

下面寫個小程序測試一下。
private Runnable runnable = new Runnable() { @Override
public void run() {
List<Book> bookList = new ArrayList<>(); for (int i = 0; i < 5000; i++) {
Book book = new Book();
book.setUuid(UUID.randomUUID().toString());
book.setName("name"); //其他set方法略
bookList.add(book);
} try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

mBookDao.insertOrReplaceInTx(bookList);
Log.d(TAG, "插入book數據:" + bookList.size());
}
};private void insert() {
Log.d(TAG, "線程池開始");
mBookDao.deleteAll(); long time = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(3); for (int i = 0; i < 200; i++) {
executorService.submit(runnable);
}
executorService.shutdown(); for (; ; ) { if (executorService.isTerminated()) { break;
} try {
executorService.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d(TAG, "線程池完成:" + (System.currentTimeMillis() - time) + "ms");
}

runnable任務模擬1秒從網路拉取5000條數據並插入DB,insert方法使用線程池執行runnable任務。
執行時間超過1000秒,查看內存佔用超過180M。如果數據量更多,肯定會發生OOM,基本上可以定位是greenDAO的問題。現在需要在兩個方面優化,一是尋找內存佔用的原因,二是提高數據的插入速度。
查看內存堆
內存的佔用隨著insert的數據量越多而遞增,從中間mp出java堆,得到hprof文件。注意這個文件不是標准格式,只能用AndroidStudio打開。

圖1
右擊文件導出標準的hprof文件,用更加強大的MAT分析。

圖2

圖3
看到IdentityScope佔了一半內存,可以確定是greenDAO緩存了插入數據。
mBookDao.insertOrReplaceInTx(bookList);mBookDao.detachAll();

greenDAO的緩存功能是有用的,沒必要關閉,改成在插入數據後,調用一次detachAll,將identityScope清空。
public void detachAll() { if (identityScope != null) {
identityScope.clear();
}
}

重建索引
對表插入大量數據,如果中間沒有涉及到業務,可以先失效索引,待插入完成後重建索引。
String sql = "drop index index_isbn";
mDb.execSQL(sql);
sql = "drop index index_publisherid";
mDb.execSQL(sql);
sql = "drop index index_author";
mDb.execSQL(sql);

插入數據前,drop掉表中的索引。沒有見到greenDAO有操作索引的方法,直接執行sql命令。
sql = "create index index_isbn on book(isbn)";
mDb.execSQL(sql);
sql = "create index index_publisherid on book(publisherid)";
mDb.execSQL(sql);
sql = "create index index_author on book(author)";
mDb.execSQL(sql);

插入數據完成後,重建索引。最後執行100w數據插入大約耗時450秒,比什麼都不做快了兩三倍。
非同步操作
上一個步驟的耗時包含了模擬網路和資料庫操作的時間,使用多線程將兩個環節分離,可以減少總時間。
greenDAO提供了AsyncSession這個非同步操作類,使用Session.startAsyncSession()獲取實例,內部實現使用了線程池和阻塞隊列,原理很簡單不用多講。
mAsyncSession.runInTx(new Runnable() { @Override
public void run() {
mBookDao.insertOrReplaceInTx(bookList);
mBookDao.deleteAll();
}
});

獲取數據後,提交給AsyncSession非同步插入資料庫。要注意在合適地方使用waitForCompletion,等待AsyncSession完成已有任務。如果獲取數據速度很快,而操作資料庫很慢,會導致過多數據緩存在AsyncSession的內部阻塞隊列。
最後測試一下100w數據插入資料庫,耗時不到150秒,又快了幾倍。

作者:展翅而飛
鏈接:https://www.jianshu.com/p/6589c6d3f551
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

D. 此時此刻,鴻蒙時刻——再說華為鴻蒙系統的那些事兒

2021年6月2日,對於華為和很多關心華為的人來說,都是一個重要的日子,因為千呼萬喚的華為鴻蒙操作系統(HarmonyOS)正式發布,雖遲但到。就像HDC 2019上鴻蒙初次發布那樣,准隨著它的爭議從未消失,且更隨著手機鴻蒙系統的推出在即,有愈演愈烈之勢。

在HDC 2019之後,我曾寫過一篇《關於華為鴻蒙系統的那些事兒》的文章,此時此刻,我覺得是時候再說說華為鴻蒙系統那些事兒了——雖然我知道,在這個當口,寫這樣一篇文章很可能給我自己挖一個大坑……

不搞懂Android,你就看不懂鴻蒙

關於鴻蒙的最大爭議點無非就是:「HarmonyOS是不是套殼Android?」要說不是,不服氣的人肯定大把,要說是,那也一樣不得了,那就一層層地說清楚。首先,讓我們看看Google手中的Android操作系統是怎麼回事。

回顧一下Android操作系統的起源。它是由知名IT人Andy Rubin於2003年10月成立的Android公司推出的產品,其本身是基於Linux內核開放源代碼的操作系統;2005年8月,Google收購了Android公司;2007年11月,Android操作系統首次亮相,同時Google宣布以Apache免費開源許可證的授權方式,發布Android的源代碼,Google牽頭的OHA也正式創立(OHA,Open Handset Alliance,該組織最初由34家手機製造商、軟體開發商、電信運營商以及晶元製造商共同組成);2008年9月,Android 1.0版本正式推出,首款Android智能手機G1發布,宣告了一個新的時代開啟。現在,Android操作系統已經成為智能手機市場第一大操作系統,也廣泛使用在智能手機之外的很多設備上。

Android的起源和開源兩個字分不開。是的,Android系統底層所使用的Linux內核,是必須遵照GPL協議進行開源傳播的(GPL協議,General Public License,簡稱GPL,通用性公開許可證)。這個協議中的一項原則就是:確保軟體自始至終都以開放源代碼形式發布,保護開發成果不被竊取用作商業發售。

因此,採用Linux內核的Android操作系統,也不能違反這個協議, 前邊提到的Android免費開源許可證授權,就是指Google要向使用該操作系統的智能手機廠商提供開放的源代碼,即AOSP(Android Open Source Project),但這部分源代碼並不代表「Android」操作系統的全部。

Google當初看上Android,可不是想要將這個開源系統作為一個免費的「慈善」項目來推動,而是在意Android這個平台的商業化潛力。於是,在收購了Android系統之後,Google就按自己的設想打造Android系統,即在開源代碼的部分之外,基於自家在移動互聯網上強大的控制力,把Gmail、Maps、Google Play、YouTube、Chrome這些我們耳熟能詳的應用服務整合為GMS(Google Mobile Services)服務包植入,從而形成了這個系統的核心競爭力—— 簡單理解Android系統的本質,就是AOSP+GMS的合體。

換句話說,智能手機廠商可以自由使用AOSP提供的免費源代碼進行自家操作系統的開發,但想要賣得好,擁有更多的用戶,卻離不開GMS包含的應用,在Android的商業模式中,Google有一套嚴格的機制在免費開源與付費授權之間取得平衡的。

之前有數據顯示,從2008年~2016年間,Android操作系統為Google供貢獻了高達310億美元的營收,而利潤更是高達220億美元,也就是說,數以億計的搭載Android操作系列和GMS服務包的智能硬體們,都成為了Google帝國的現金奶牛。

只是,Google這個龐大的商業帝國,卻總有不能企及的地方——中國大陸。早年因為不願意服從法律監管,Google幾乎將整個互聯網服務都移出了中國大陸市場,但是Android操作系統卻隨著移動互聯網和智能手機的發展,在中國市場壯大。

這里有一個非常有意思的現象:因為Google不能在中國提供服務,中國的智能手機廠商們,早就習慣了自主開發沒有GMS,但又包含完整本地化服務的自主UI,但因為要面向全球市場,所以又會在自主UI中保留Google GMS框架,這樣就可以在海外市場很方便地接入GMS並激活一系列的服務。

因為GMS服務不能進入中國大陸市場,手機廠商們會在這個基礎上接入很多自己的服務,比如應用商店、主題商店、內容、支付、推送等,可是沒有Google Play的應用審核機制,國內的軟體生態是啥樣大家都看到的,到最後手機廠商自己都受不了了,才有了「統一推送聯盟」、「軟體綠色聯盟」之類的組織,且隨著國家監管力度的加強,現在已經好多了。

隨著Android的市場地位越來越強,Google也開始做一些小動作——畢竟這家公司的口號在2015年就從「Do not be evil」變成了「Do the right thing」。如將一些關鍵特性和重要代碼的更新放入GMS包的版本迭代中,比如部分組件、驅動等,有意拉開Android與AOSP的代數差距,從而凸顯自己的地位,進一步強化對Android生態的控制力。所以,為了能讓自家的UI能有更強的市場競爭力,智能手機廠商們對Android的魔改從來就沒有停止過。

回到華為。2019年5月16日,華為被美國商務部列入實體清單,被視為美國對華為終極打壓的開始,首當其沖的就是銷往全球的華為新款手機不能再使用Android系統。

是的,華為的確是不能使用Google的Android操作系統了,但更具體的描述應該是: 「華為不能在自家手機新品中內置GMS服務,但AOSP源代碼的使用絲毫不受影響」, 而非那段時間盛傳的華為手機從此變磚。但是,無法內置GMS,對於華為手機在全球市場的銷售影響是實實在在的,但好在對於系統本身進化影響並不大——現在讓我們來到第二個話題:「華為掏空Android。」

華為真的掏空了Android?

華為是否掏空了安卓?這應該是每過一段時間就會被拉出來遛一圈兒的問題。其實在我看來, 答案:是也不是。為什麼說不是?因為AOSP還在呢,華為從來沒有說過要排斥這個開源項目的,畢竟在這個軟體生態上運行著數以百萬計的應用,真要把這個掏了,難不成華為要自己做一個全新的軟體生態,腦子抽了還差不多。為什麼說是?因為華為對Android操作系統的改變也是真實的,很多谷歌做的東西,很多都被華為自己的東西替代了。

這個涉及一個主角, 即EMUI,華為自主開發的UI,或者說兩個主角也行,EMUI+HMS。 在這其中,現任華為消費者BG軟體部總裁王成錄王博帶領的EMUI團隊顯得尤其重要,從他2016年加入這個團隊之後,EMUI的根本性改變就發生了,用他的話說:「EMUI不僅僅是一個UI,而是一個平台。」EMUI是如何從UI變為平台的呢?簡單梳理一下:

-EMUI 4.X時代,主要的變化還只是TEE OS(即用於指紋的TustZone)以及SensorHub這樣基於硬體功能的模塊上;

-EMUI 5.X時代,這是一個戰略級別的關鍵版本。解耦Android底層組件,精簡各子模塊。虛擬機在這個版本也得到了優化,特別涉及了垃圾回收機制(GC)、AOT(運行前編譯)、資料庫優化(IO並行)等。在這個版本,新的文件系統F2FS(針對快閃記憶體推出,大幅度減少文件碎片),還有UltraMemory(即4GB運存達到友商6GB運存效果)的推出,通過對各個Android底層技術模塊的深度開發,讓EMUI團隊敢於將「十八月不卡頓」放到了公眾面前,沒記錯這就是EMUI第一個大爭議點出現;

-EMUI 8.X時代,人工智慧技術加入系統,iAware借著算力,整個系統的後台管理模式更合理,圖形引擎得到升級,即半路加入的GPU Turbo,這是EMUI對Android系統全棧圖形模塊修改的開始,EROFS超級文件系統也在此期間亮相開源社區;

-EMUI 9.X時代,也是「Turbo」的時代,GPU Turbo 2.0、CPU Turbo、LinkTurbo都是在這一代出現的,系統性能繼續優化,EROFS正式加入,連接能力得到強化。2019年MWC上,華為「1+8+N」智慧全場景戰略首次浮出水面,在這背後,鴻蒙的研發其實已經悄悄進行了不短的時間了;

-EMUI 10.X時代,分布式技術、軟匯流排、超級終端這一系列的概念出現了,它在HDC 2019上推出,伴隨著它一起發布的就是鴻蒙1.0,其時還是一個半成品,只能叫操作系統內核。只是因為2019年5月16日的事件,它不得不作為戰略產品提前亮相,在推出的時候,鴻蒙就直接宣布將會開源;

-EMUI 11.X時代,鴻蒙來到了2.0版本,但HDC 2020的主角是HMS和AppGallery,不但前邊提到的一系列系統底層的能力變化全部被涵蓋其中,連Google最引以自傲的營收來源GMS服務、Google Play也被替代了。

看完上邊這個簡單的梳理,你是不是對本章節開頭的那個問題概念更明晰了? 如果說華為掏空了Android,沒錯,華為EMUI團隊覺得Google做得不好的地方,要麼魔改,要麼就乾脆換掉,比如底層連接協議。 特別是在2019年5月16日之後,即EMUI10和11兩代,這樣的動作愈加突出,幅度也越來越大。

要說華為沒有掏空Android,也沒錯, 因為現在華為完全自主運營的AppGallery應用商店,里邊的應用都是基於AOSP規范開發,但又置入了HMS服務的華為版,目的就是為了解決這些應用在沒有GMS支持下的消費者體驗問題。 畢竟在全球范圍內,華為已經積累了7億多終端用戶,在他們換機或是華為解決手機硬體產品問題之前,用戶還是要繼續使用這些華為手機和軟體服務的。

到這里,為什麼會有鴻蒙這個東西了應該也有答案了。 「低情商」的說法,它有點像是華為在EMUI進化過程中,用來解決多設備連接協作問題中的「副產品」;「高情商」的說法,它是包涵底層互聯協議、晶元能力調用、多設備協同過程中交互界面等全方位解決方案的集合體,高效率的連接(HiLink)、低時延(HiLink)以及微內核(比如LiteOS)是它的三大特點,所以,從軟硬體一體化的整體度來說,鴻蒙肯定就是一個全新的操作系統。

因為華為的工程師認為,當前物聯網的連接協議太過碎片化,從業廠商開發理解能力參差不齊,所以最後出來的產品也就五花八門,這樣的情況,將會嚴重影響華為「1+8+N」戰略的推進效果,「1+8」都是華為自己的好說,「N」怎麼辦呢?那就交給鴻蒙來解決吧。

這是發布會後宣布的消息:2020年和2021年,華為按計劃分兩次把HarmonyOS的核心基礎能力全部捐獻給開放原子開源基金會,由開放原子開源基金會整合其他參與者的貢獻,形成 OpenHarmony 開源項目——這和AOSP是不是差不多?這就是為了能讓其他有興趣加入華為「1+8+N」戰略的設備製造和服務提供商能更好的理解這個生態系統。在2021年5月18日上海的華為HarmonyOS Connect夥伴峰會上,華為消費者業務AI與智慧全場景業務部副總裁楊海松還提到了鴻蒙的商業模式,包括免費認證服務這些內容,我有整理專訪,大家有興趣也可以了解一下。

在2019年發布鴻蒙1.0的時候,華為的確是沒有那麼快的計劃將它放在智能手機上。HDC 2019之後對余承東的專訪中,他是這樣說的:「如果我們確認谷歌不再為華為提供操作系統,那麼,我們可以在一夜之間通過升級,將所有的華為手機操作系統的內核更換為鴻蒙,但是我們現在並不打算這么做,因為我們還是希望可以讓合作夥伴(主要是指美國公司)的利益最大化。」

但同時,他也說了三個「Ready」,意即華為是可以隨時這么做,而在6月2日的發布會上,華為手機的鴻蒙升級計劃是何等規模大家也看到了。同樣的問題王博早些時候的回答也是:「做操作系統並沒有難度,關鍵是商業模式的問題。」

時間來到2020年5月16日,美國針對華為的終極制裁到來,手機SoC晶元斷供,蓬勃發展的華為手機業務隨時面臨停擺的問題。雖然現在看,華為還可以通過購買第三方公司的晶元,在全球繼續推出4G手機產品,但GMS同樣不能使用,出貨量也會從過去的億級下降到千萬級,決定華為消費者業務未來的「1+8+N」也隨之面臨巨大的挑戰。兩年前還是商業模式的問題瞬間就變成生死存亡的關鍵,HarmonyOS變得意義更加重大,不得不發。

並肩前行的OpenHarmony和HarmonyOS

我相信有了前邊兩個部分的鋪墊,再進入第三個部分,很多人的困惑應該會少很多。華為目前對鴻蒙這個操作系統的定義是: 「HarmonyOS是新一代智能終端操作系統,為不同設備的智能化、互聯與協同提供了統一的語言」 ,它與我們使用的Android這種宏內核系統在思路上有著本質的區別。

宏內核操作系統我們用得很多,電腦上的Windows、手機上Android都是,它最大的特點是設備要裝載這個操作系統,就得所有的系統組件全部加包一起裝載,不管用不用得著,同時在運行時,系統也會依據內存大小,自動載入組件,響應速度是提升了,但會消耗極大的系統資源。

到2021年我們已經能見到最高達18GB RAM的安卓手機了,而在當前主流的Android 11系統描述中寫到:「設備最小運行內存為512MB」。如果設備的運行內存小於512MB,要到不能用最新版本的Android系統,要麼就只能用老版本——這也是為什麼我們能看到有些車機還在跑Android 4.4版本……

但是鴻蒙的設想就恰恰是反過來,它從架構設計上就進行了全棧解耦,將龐大的操作系統打散,拆解成很小的顆粒,不同能力的設備只需要按自己的要求來選擇相應的模塊能力載入即可, 比如鴻蒙系統的前身LiteOS,它最小的體積只有10KB,你能相信它是操作系統么?可它就是!華為認為這是未來物聯網時代和必然趨勢,巧的是Google也同樣這樣認為,所以,足足被其孕育了5年的微內核操作系統Fuchsia,剛剛於近日才正式推送,它的目標就是替代Android和ChromeOS,從而更好地適應物聯網時代的多樣終端和生態。

為了更好地讓合作夥伴與開發者適配設備與系統的能力,華為將採用鴻蒙系統的設備從L0~L5做了6個分級,其中從L0~L2這三個級別的設備,要麼沒有交互界面,要麼交互和功能都非常簡單,家電、手環就算這種設備,運行內存也非常小,甚至低到KB級,其被定義為瘦終端,它們採用的鴻蒙系統,代碼百分之百來自華為,不包含AOSP的任何部分;而L3~L5這三個級別的設備,有交互界面,可應用擴展,手機、平板、筆記本電腦、車機、VR/AR等這些設備就屬於富終端的類別,它們採用的鴻蒙系統,就會引用AOSP的部分代碼。在這其中,手機無疑是功能最復雜的核心設備,會跑最多的應用,它引用AOSP順理成章。

所以,這次發布的HarmonyOS是何物就好解釋了。 華為軟體團隊開發出的OpenHarmony開源項目用來構建「1+8+N」生態的基礎,在這個基礎上,華為手機終端團隊加入HMS服務包,提供全套華為服務和連接能力,包括嵌入HMS服務的華為版應用,再加上部分AOSP開源代碼,支持Android廣泛的應用生態,保證消費者可以繼續無障礙地使用已有的應用 ,這就是今天發布的HarmonyOS。看到這里,是不是有人感覺眼熟?

沒錯,蘋果現在M1平台的MacBook就差不多是類似的情況,它既可以運行macOS應用,又可以運行iOS應用,而HarmonyOS呢,既可以運行原來的Android(APK)應用,又可以運行鴻蒙平台開發的應用(APK)。所以,6月2日發布會王博演講的最後一個環節的話不曉得各位注意到沒有: 「HarmonyOS是基於OpenHarmony的第一個公開發行版」 ,也算是把兩者的關系做了一個比較明確的定義了。

關於鴻蒙系統是否是完全自主開發,要是沒記錯,華為自己是從來沒有說過這樣的話,但「我們要站在巨人的肩膀上」之類的話倒是看到過不少, 這個巨人放在HarmonyOS上,就是AOSP。至於有人說到的鴻蒙上使用的代碼老舊,經過前邊兩個章節的介紹你應該明白,這對現在的華為和EMUI來說並不太重要,因為Android操作系統最核心的模塊,華為早就已經是脫離谷歌自己在做更新,包括HMS加入後,連應用驗證都自己在做,依賴度已經非常低了。

所以,現在EMUI 11還只基於Android 10版本的AOSP代碼,但其對比採用Android 11版本的友商系統體驗如何,相信大家心裡是有數的。只是因為環境的關系, 本來應該「慢工出細活」的事情,全部被按下了快進鍵,很多還沒來得做的事情,也都因為時間不夠沒有完成,比如代碼替換等,相信今年的HDC 2021上華為軟工團隊會有更多新消息放出。

選擇在現在推出HarmonyOS,對於華為也是有風險的,早年阿里YunOS與Android商業生態的沖突讓我們第一次理解到了Google對「開放」的態度。現在,HarmonyOS可能面臨的情況也差不多,但好在華為有HMS和初具規模的AppGallery可以進行一些對沖。

但對比這樣的風險,真正的風險還是時間。從2020年5月16日算起,到現在已經過去了一年,消費者的換機周期是28個月左右,留給華為以手機產品為中心推進「1+8+N」戰略的時間並不多,在餘下的短短1~2年時間里,華為除了繼續保留盡可能多的存量用戶,還需要完成去手機中心化的「1+8+N」戰略,還需要團結盡可能多的手機廠商來形成新的中心,從之前與楊海松的對話來看,新戰略中的「1」,很有可能就是App了。

但另一方面,楊海松也說過: 「華為擅長做產品而不擅長做生態」,這也是一個現實的問題,以前華為做產品,秉持的是「進入一個行業,就一定要做到世界第一」的「霸道」原則,現在做生態,華為應該想的是如何交到更多朋友,合作共贏,姿態非常重要……

寫在最後

「華為推出HarmonyOS,中國驕傲」,發布會之後,以此為主題,各種各樣的雞血文章、小視頻又出現在各大內容平台上,好一場流量盛宴。類似的場景也出現在一年前,在他們口中,似乎華為能以一己之力,一夜之間釐清中國整個晶元產業的 歷史 欠賬。華為人並非沒有看到這些,但現在的他們,哪裡有功夫去理會這些論調,有太多事要做了。雖然這篇長文,也許看到的人和看完的人有限,但我覺得能把那些關於HarmonyOS的事兒解釋清楚,足矣。

E. 怎麼提高android contentresolver的查詢效率優化

兩種辦法:
1.創建自己的ContentProvider,需要繼承ContentProvider類
2.如果你的數據和已存在的ContentProvider數據結構一致,可以將數據寫到已存在的ContentProvider中
當然前提是獲取寫該ContentProvider的許可權.比如把OA中的成員通訊信息加入到系統的聯系人ContentProvider中
ContentProvider基礎
所有ContentProvider都需要實現相同的介面,用於查詢ContentProvider並返回數據.也包括增加、修改和刪除數據.
步驟:
1.獲得一個ContentResolver的實例,可通過Activity的成員方法getContentResovler()方法:
ContentResolver cr = this.getContentResolver();
ContentResolver實例帶的方法可實現找到指定的ContentProvider並獲取到ContentProvider的數據
ContentResolver的查詢過程開始,Android系統將確定查詢所需的具體ContentProvider,確認它是否啟動並運行它.
android系統負責初始化所有的ContentProvider,不需要用戶自己去創建.實際上,ContentProvider的用戶都不可能直接訪問到ContentProvider實例,只能通過ContentResolver在中間代理.
2.數據模型
ContentProvider展示數據類似一個單個資料庫表.
其中:
每行有個帶唯一值的數字欄位,名為_ID,可用於對表中指定記錄的定位.
ContentProvider返回的數據結構,是類似JDBC的ResultSet,在android中,是Cursor對象.
URI,每個ContentProvider定義一個唯一的公開的URI,用於指定到它的數據集.
一個ContentProvider可以包含多個數據集(可以看作多張表),這樣,就需要有多個URI與每個數據集對應.
這些URI要以這樣的格式開頭:
content://
表示這個URI指定一個ContentProvider.
如果你想創建自己的ContentProvider,最好把自定義的URI設置為類的常量,這樣簡化別人的調用,並且以後如果更新URI也很容易.
android定義了CONTENT_URI常量用於URI,如:android.provider.Contacts.Phones.CONTENT_URI
2.查詢ContentProvider
要想使用一個ContentProvider,需要以下信息:
定義這個ContentProvider的URI,返回結果的欄位名稱,這些欄位的數據類型
如果需要查詢ContentProvider數據集的特定記錄(行),還需要知道該記錄的ID的值.
構建查詢
查詢就是輸入URI等參數,其中URI是必須的,其他是可選的,如果系統能找到URI對應的ContentProvider將返回一個Cursor對象.
可以通過ContentResolver.query()或者Activity.managedQuery()方法.
兩者的方法參數完全一樣,查詢過程和返回值也是相同的.
區別是,通過Activity.managedQuery()方法,不但獲取到Cursor對象,而且能夠管理Cursor對象的生命周期.
比如當Activity暫停(pause)的時候,卸載該Cursor對象,當Activity Restart的時候重新查詢.另外,也可以對一個沒有處於Activity管理的Cursor對象做成被Activity管理的,通過調用Activity.startManaginCursor()方法.
類似這樣:
Cursor cur = managedQuery(myPerson,null,null,null,null);
其中第一個參數myPerson是Uri類型實例.
如果需要查詢的是指定行的記錄,需要用_ID值,比如ID值為23,URI將是類似:
content://....../23
android提供了方便的方法,讓開發者不需要自己拼接上面這樣的URI,比如類似:
Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI,23);
或者:
Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI,"23");
二者的區別是一個接收整數類型的ID值,一個接收字元串類型.
其他幾個參數:
names,可以為null,表示取數據集的全部列,或者聲明一個String數組,數組中存放列名稱,比如:People._ID.一般列名都在該ContentProvider中有常量對應;
針對返回結果的過濾器,格式類似於SQL中的WHERE子句,區別是不帶WHERE關鍵字,如果返回null表示不過濾,比如name=?;
前面過濾器的參數,是String數組,是針對前面條件中?佔位符的值;
排序參數,類似SQL的ORDER BY字句,不過不需要寫ORDER BY部分,比如name desc,如果不排序,可輸入null.
返回值是Cursor對象,游標位置在第一條記錄之前.
下面實例適用於android 2.0及以上版本,從android通訊錄中得到姓名欄位:
java代碼:
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
讀取返回的數據
如果在查詢的時候使用到ID,那麼返回的數據只有一條記錄.在其他情況下,一般會有多條記錄.和JDBC的ResultSet類似,需要操作游標遍歷結果集,在每行,再通過列名獲取到列的值,可以通過getString()、getInt()、getFloat()等方法獲取值.
比如類似下面:
java代碼:
while(cursor.moveToNext()) {
builder.append(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))).append("-");
}
和JDBC中不同,沒有直接通過列名獲取列值的方法,只能先列名獲取到列的整型索引值,然後再通過該索引值定位獲取列的值.
編輯數據
可以通過ContentProvider實現以下編輯功能:
增加新的記錄:
在已經存在的記錄中增加新的值、批量更新已經存在的多個記錄、刪除記錄.
所有的編輯功能都是通過ContentResolver的方法實現.一些ContentProvider對許可權要求更嚴格一些,需要寫的許可權,如果沒有會報錯.
增加記錄
要想增加記錄到ContentProvider,首先,要在ContentValues對象中設置類似map的鍵值對,在這里,鍵的值對應ContentProvider中的列的名字,鍵值對的值,是對應列希望的類型.
然後,調用ContentResolver.insert()方法,傳入這個ContentValues對象,和對應ContentProvider的URI即可.返回值是這個新記錄的URI對象.這樣你可以通過這個URI獲得包含這條記錄的Cursor對象.
比如:
java代碼:
ContentValues values = new ContentValues();
values.put(People.NAME,"Abraham Lincoln");
Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
在原有記錄上增加值
如果記錄已經存在,可在記錄上增加新的值,或者編輯已經存在的值.
首先要找到原來的值對象,然後要清除原有的值,然後像上面增加記錄一樣即可:
java代碼:
Uri uri = Uri.withAppendedPath(People.CONTENT_URI, "23");
Uri phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
values.put(People.Phones.NUMBER, "1233214567");
getContentResolver().insert(phoneUri, values);
批量更新值
批量更新一組記錄的值,比如NY改名為Eew York.可調用ContentResolver.update()方法.
刪除記錄
如果是刪除單個記錄,調用ContentResolver.delete()方法,URI參數,指定到具體行即可.
如果是刪除多個記錄,調用ContentResolver.delete()方法,URI參數指定Contentprovider即可,並帶一個類似SQL的WHERE子句條件.這里和上面類似,不帶WHERE關鍵字.
創建自己的ContentProvider
創建contentprovider,需要設置存儲系統.大多數ContentProvider使用文件或者SQLite資料庫,不過你可以用任何方式存儲數據.android提供SQLiteOpenHelper幫助開發者創建和管理SQLiteDatabase.
繼承ContentProvider,提供對數據的訪問.在manifest文件中聲明ContentProvider.繼承ContentProvider類
必須定義ContentProvider類的子類,需要實現如下方法:
java代碼:
query()
insert()
update()
delete()
getType()
onCreate()
在實現子類的時候,還有一些步驟可以簡化ContentProvider客戶端的使用:
定義public static final Uri常量,名稱為CONTENT_URI:
java代碼:
public static final Uri CONTENT_URI = Uri.parse("content://com.example.codelab.transportationprovider");
如果有多個表,它們也是使用相同的CONTENT_URI,只是它們的路徑部分不同.
聲明ContentProvider
創建ContentProvider後,需要在manifest文件中聲明,android系統才能知道它,當其他應用需要調用該ContentProvider時才能創建或者調用它.
語法類似:
<provider android:name="com.easymorse.cp.MyContentProvider"
android:authorities="com.easymorse.cp.mycp">
</provider>
android:name要寫ContentProvider繼承類的全名.
android:authorities要寫和CONTENT_URI常量的B部分

F. android sqllite 怎麼過濾重復數據

查詢語句優化下 加上DISTINCT關鍵字去重
另外 獲取數據過來之後還可以利用list集合再次去掉重復值