Android快速實現地圖功能(不只快!並且小!)

  • 本文爲 Marno 原創,轉載必須保留出處!
  • 公衆號【 aMarno 】,關注後回覆 RN 加入交流羣
  • React Native 優秀開源項目大全:www.marno.cn

1、前言

本文旨在提供一個解決思路,不只適用於添加地圖這一種場景。還有更多的場景能夠用到,好比展現在線 PDF 文檔等。javascript

最近都在忙着討論項目需求,忙着學習 React Native ,時間一久都快忘記我是一個搞 Andorid 開發的了。今天忽然想到了本身在上個項目期間的一個經歷。以爲可能會對一些人有幫助,因而就寫出來和你們分享一下!css

上個項目是一個 O2O 類型的項目,在更新了幾個版本以後,老闆打算進行推廣,進行地鐵廣告,電梯廣告,地推等等。讓我把 Apk 大小優化一下,說如今的10M太大了。不利於用戶下載。html

2、窮途末路

其實我在寫代碼的時候已經很剋制了。除了一些必備的三方庫之外,基本也沒有引入什麼其餘多餘的東西。並且我已經作了如下優化工做:java

  • 優化圖片大小android

    1.使用 tinyPNG 壓縮圖片大小
    2.有些圖片換成 webP 格式,如背景圖
    3.icon 圖標僅保留一套,使用時將 ImageView 大小限制死。僅保留極個別不一樣分辨率的圖標。
    4.部分icon 使用 svg 代替,少許web

  • 優化佈局api

    1.優化層級,減小布局嵌套
    2.一個界面一個界面的消除過渡繪製
    3.多使用 include 標籤,重用佈局
    4.沒必要要的佈局使用 ViewStub 延遲加載(用的不多)
    5.將可複用資源抽取到對應的 res 文件中,如字符串,樣式等微信

  • 優化代碼ide

    1.實體類去除沒用到屬性,並將屬性設爲 public ,去除 get / set 方法
    2.減小內部嵌套的實體類,尤爲像 GsonFormat 這樣的工具生成的實體類
    3.能服用的儘可能複用。
    4.還剔除了一部分我本身經常使用的打包好的工具類中一些沒調到的方法。
    5.不過,僅是減小几行代碼,對 Apk 體積的優化成效甚微。svg

  • 優化三方庫的使用

    1.Glide 仍是 Picaso 糾結了好一陣子。Picaso 要小不少
    2.推送,統計,三方登陸,微信支付,地圖,這個無法刪。可是優化了一下 so 適配CPU的數量。

通過了這些工做後(可能有遺漏,時間過久記不太清了),老闆還讓我優化 Apk 大小,我就實在是想不到其餘辦法了。並且我把網上能搜到的關於 Apk 優化的文章基本都看了,只要是能用的都會去試一下。但除了圖片之外的優化都收效甚微。

3、靈光一閃

我把 Apk 傳到 nimbledroid.com 上進行了分析,發現其中最佔體積的就是【百度地圖】了,足足佔了 6M 多。可是咱們做爲 O2O 產品怎麼可能沒有地圖呢?這是產品經理也不會贊成的啊。因而我苦思冥想,採起了曲線救國的方式,幹掉了百度地圖,最終將那個版本的推廣 Apk 包減少至僅有 3.34M。(因爲已經離職,下圖就不顯示App名稱了,除非有廣告費,哈哈哈~)

思路很簡單,就是用 JS 的地圖替換了原生的地圖。由於我分析了一下地圖在這個 App 的功能佔比,其實算是一個比較弱的功能,用戶要想看到地圖頁面,必須經歷如下的流程。

在App中的體驗就是這樣的↑↑↑

如上圖所示,這個頁面的層級比較深,並且根據前面幾個版本的頁面統計數據來看,確實不多有用戶點到這個界面來。可是又不能沒有這個功能,因此最終採起了這樣折中的辦法。性能怎麼樣呢?再來個圖給你們看下吧。

我以爲性能仍是能夠接受的,雖然不如原生加載的快,可是我很滿意了,由於我把安裝包縮小了(用到的導航功能是跳轉外部地圖)終於能夠交差了,並且產品經理和老闆都沒有看出和以前地圖的差異來,只是以爲這個小夥子還挺屌的,真的給搞到只剩下3M了(嘿嘿~)。

4、代碼實現

相比集成原生地圖,集成 JS 地圖簡直就是不能再更簡單了!! 不用下載煩人的 jar 包,不用考慮 so 文件的兼容。並且我以爲 JS 地圖只有性能上不如原生,在功能上貌似還要更豐富一點。固然這裏只是用於簡單的地圖展現和添加一個 Marker,更多功能能夠自行探索。

可是最開始集成的時候我仍是遇到了坑,剛開始使用的是百度的 JS 地圖,可是發如今經過 Native 代碼調用 JS 代碼設置 Marker 的時候,百度總設置失敗。網上查了好久,總以爲步驟方法都沒有錯,可是就是不行,正當我打算放棄這個念頭的時候,想起來不是還有高德地圖的麼,因而試了一下果真就好了。

先大概說一下步驟:

  1. 到開發者平臺申請 JS 地圖的祕鑰
  2. 在 assets 目錄下建立一個離線的 html 頁面
  3. 在 WebView 中加載該離線頁面
  4. 經過 Native 調用 JS 方法,在地圖上添加 Marker 圖標

第一步就不用我說了吧,直接從第二步開始吧。【2】在 assets 目錄下建立一個離線地圖 html 網頁【amap.html】,代碼以下↓↓↓,注意看註釋!!這裏可能須要咱們會一點 HTML 和 JS 的知識。速成就行了,只要明白一個 html 頁面是如何搭建起來的就行。

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <title>基本地圖展現</title>
    <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/>

    <style type="text/css"> html,body{ width:100%; height:100%; } #container{height:600px;} </style>
    <!--<script src="http://cache.amap.com/lbs/static/es5.min.js"></script>-->
    <script src="http://webapi.amap.com/maps?v=1.3&key=這裏填寫你申請的 key"></script>
    <!--<script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>-->
</head>
<body>
<div id="container"></div>

<script> var map = new AMap.Map('container', { resizeEnable: true, zoom:14, center: [104.065794,30.657483] }); //提供JS方法,讓webview調用,添加marker function addMarker(lng,lat) { map.setZoomAndCenter(14, [lng, lat]); marker = new AMap.Marker({ //指定 Marker 的樣式 icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png", position: [lng, lat] }); marker.setMap(map); } </script>
</body>
</html>複製代碼

【3】而後建立一個帶 WebView 控件的 Activity 頁面,在代碼中將該 WebView 的 setJavaScriptEnabled() 方法設置爲 true,而後經過 webview 加載 asstes 中編寫好的離線地圖 amap.html 文件。

mWebView.loadUrl("file:///android_asset/amap.html");複製代碼

【4】最後在 JS 地圖上設置 Marker 就行。這裏涉及到了 Native 調用 JS 代碼,不熟悉的能夠搜索一下。

mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                //調用JS方法,將商家座標設置到地圖上
                mWebView.loadUrl("javascript:addMarker(" + shopLng + "," + shopLat + ")");
            }
        });複製代碼

5、結語

這個 App 是一年多之前寫的了,由於最近在學習 React Native,就忽然回想起了那次經過 JS 解決問題的經歷。 因此寫出來和你們分享一下。其實還有不少業務能夠經過這種思路去解決,可是經過 WebView 調用 JS 代碼畢竟仍是存在性能上的侷限性,因此纔會出現像 RN 這樣的技術。恩...看來仍是要早點把 RN 學好才行!哈哈~

看完點個關注唄!我有個 RN 羣就缺你這樣的人才。早點來吧~
公衆號回覆 RN ,就送你入羣「邀請碼」。你想啥呢?我這是正經邀請碼哈!


文章看完了,歡迎關注個人公衆號【aMarno】。近期主要分享 React Native 技術!(偶爾也會閒扯淡)

相關文章
相關標籤/搜索