Android Weekly Notes Issue #235

来源:http://www.cnblogs.com/mengdd/archive/2016/12/16/6186829.html
-Advertisement-
Play Games

本期內容包括: 開發一個自定義View併發布為開源庫的完整流程介紹; 用`AnimatedVectorDrawable`實現的動畫; 什麼樣的程式是可測試的; `DownloadManager`介紹; Okhttp的重試; Android 7取消了`file://`; Android Studio即... ...


Android Weekly Issue #235

December 11th, 2016
Android Weekly Issue #235
本期內容包括: 開發一個自定義View併發布為開源庫的完整流程介紹; 用AnimatedVectorDrawable實現的動畫; 什麼樣的程式是可測試的; DownloadManager介紹; Okhttp的重試; Android 7取消了file://; Android Studio即將推出的build cache功能; 支持離線模式的app構架; 如何寫自定義的lint規則; Epoxy, 一個處理複雜RecyclerView屏的庫; FragmentPagerAdapterFragmentStatePagerAdapter的比較等.

ARTICLES & TUTORIALS

Make an android custom view, publish and open source

作者開發了一個環形的SeekBar, 並把它作為一個庫發佈到了JCenter.

作者首先講了自定義View的實現:
首先是關於View生命周期的介紹, 在寫自定義View的時候有幾個關鍵的生命周期回調需要處理:
view-lifecycle-diagram-lite-version

作者實現的幾個關鍵步驟講解:

  • 自定義屬性並獲取.
  • onMeasure()中控制尺寸.
  • onDraw()中繪製: 避免在onDraw()中分配記憶體; 用invalidate()方法來激發重繪.
  • onTouchEvent()處理用戶手勢. 在他的環形SeekBar的實現里, 這裡涉及到了點擊坐標到角度的轉換.

將自定義View庫開源到Github:
開源到Github有個好的README很重要, 這裡有幾個tips:

  • 提供截圖, Gif或者Video.
  • 提供安裝/使用說明.
    作者自己的庫: SwagPoints

發佈庫:

  • JFrog Bintray註冊.
  • 創建repository, package, 和版本號.
  • 生成並上傳, 用了這個library.
  • 添加到Jcenter.
  • 被接受之後收到郵件, 就可以使用了.

Animation: Jump-through

AnimatedVectorDrawable實現的一個很fancy的位置標誌動畫.

What makes Android Apps Testable

如果程式的架構不適合測試, 那麼硬要寫一些測試很可能就會面臨這樣的局面: 要麼就是發現沒法寫測試, 要麼就是為了寫測試而破壞了代碼, 做了一些奇怪的事情.

那麼到底是什麼樣的程式才是適合寫測試, 或者是可測試的呢?

有一個有趣的定義是seam(接縫), 在接縫處你可以改變程式的行為, 而不用編輯當前程式. 如果程式沒有接縫, 你將無法設置測試的初始條件和驗證測試結果.

本文中舉了一個實際的例子, 開始的時候程式沒有seam, 所以導致無法測試, 後來把靜態方法改為實例的方法之後, 我們就可以通過Mockito來模擬行為, 設置條件, 最後通過驗證某一方法的調用與否來進行驗證.

DownloadManager – Part 3

DownloadManager來處理下載.
首先它在設備上有自己的UI, 還有notification, 還有Downloads app能讓用戶管理下載文件.

我們可以查詢到文件的一些信息, 比如MIME type, 文件尺寸, 下載狀態等.

我們還可以用getUriForDownloadedFile()方法來獲取一個URI, 配合MIME type, 發送Intent, 來打開一個相關的查看程式.

關於儲存文件的合適地點:

  • 文件小, 僅app自己使用 -> 私有數據區域(預設行為).
  • 文件大, 僅app自己使用 -> 外部存儲的私有數據區域(不需要許可權). setDestinationInExternalFilesDir().
  • 文件需要被別的應用訪問 -> 外部存儲的共有區域, 需要WRITE_EXTERNAL_STORAGE許可權. setDestinationInExternalPublicDir().

OkHttp is quietly retrying requests. Is your API ready?

在網路較慢或不穩定的時候, OkHttp有可能會重覆發送請求, 直到成功.

這個重試的邏輯是通過RetryAndFollowUpInterceptor.java實現的.

那麼, 我們可以關掉這個重試行為嗎? 有一些issues就在討論這個問題: Issue # 1043. 後來有兩個pull requests: PR #1259PR #2479改進了這個問題, 減少(但並沒有消除)了不必要的retry請求.

全局關閉重試行為: OkHttpClient.Builder .retryOnConnectionFailure()設置為false. 但是註意這樣是很粗暴並具有破壞性的, 消除了retry邏輯帶來的好處:

  • 如果Url有多個IP, 失敗了一個還可以試另一個.
  • 連接池中的連接偶爾會time out, 減少這種意外導致的後果.
  • 可以順次查找多個代理, 如果都失敗了再轉向直接連接.

解決真正的問題: 關閉靜默重試在某些情形下有幫助, 但是其實它隱藏了真正的問題, 就是你的API是否是冪等的idempotent. server端可以根據客戶端的GUID來檢測重覆, 這樣server就不會多次執行操作, 會通知發送者.

File scheme is now not allowed with Intent on N

Android N (Nougat, API 24)開始, 不再允許發送file://的Intent, 將會直接拋出FileUriExposedException異常.

所以當你把targetSdkVersion改為24之後, 你必須要確保你修複了這些問題再發佈.

解決方案是什麼呢? 用content://, 結合FileProvider:
首先在manifest裡面聲明:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

然後在res\xml\provider_paths.xml文件里指明路徑:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

最後, 把

Uri photoURI = Uri.fromFile(createImageFile());

改為

Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
        BuildConfig.APPLICATION_ID + ".provider",
        createImageFile());

然後放在Intent里發送就好了.

註意, 如果你的targetSdkVersion還沒有更新到24, 那麼即便是在Nougat的手機上file://也仍然是能正常使用的.

Use Android Studio Gradle Build Cache for faster builds

Android Studio當前的最新版是2.3 Canary 2. 有一些新的改進, 但是其中最吸引人的是這個build cache. 它會使你的clean build更快.

本文後面解析了build cache的工作原理.

Offline App Architecture, build for the Next Billion

一個好的應用應該在網路不好甚至離線的時候仍然可以使用, 我們應該做些什麼呢?

  • 確定連接狀況. 可以使用這個network-connection-class. 如果你使用的是Okhttp, 可以加一個Intercepter來進行採樣.
  • 有效地緩存. 從網路取數據很慢並且昂貴, 所以有效地利用之前取到的數據是很關鍵的優化. (Cache-Control, Etag).
  • 在本地操作, 在全局同步. 等網路請求的時候可以先顯示本地數據, 而不是loading.
  • 有效地處理線程.
  • 優化圖片. 網路不好的時候先用RGB_565, 等網路變好了再取高質量圖片.
  • 使用大Cookie. 儘量一次傳輸更多的數據(big cookie), 而不是頻繁發送一些小請求(small cookies).

Writing custom lint rules and integrating them

如何創建自定義的lint規則.
事情的由來是作者發現了一個死迴圈調用, 然後他想做一個什麼標記以防以後其他人會犯同樣的錯誤.

然後他想到的是@Nullable註解, 的檢查, 實質是依靠lint來實現的.

於是他自己寫了一個自定義的lint規則, 來提示使用用他的註解@CarefulNow標記的方法時應當註意.
詳細的實現方式請看原文.

Epoxy: Airbnb’s View Architecture on Android

epoxy是一個Android庫, 用來處理複雜的RecyclerView屏. 本文介紹了它在項目中實際的使用.

Adventures with FragmentStatePagerAdapter

可能有很多Android開發者對於
FragmentPagerAdapterFragmentStatePagerAdapter的區別不是太清楚或根本不知道, 本文作者就具體介紹了二者的不同.

基本不同

FragmentPagerAdapter
適用於項目個數確定的情形.
為什麼呢? 因為一旦fragment的實例被創建, 它永遠也不會從FragmentManager中移除, 直到Activity被銷毀.

當Fragment不見的時候, 僅僅是onDestroyView()被調用, 當fragment再次回來時, 再調用onCreateView().

FragmentStatePagerAdapter
當fragment的實例不可達的時候, 實例就會立即從FragmentManager移除. 被移除的fragment實例的狀態由FragmentStatePagerAdapter保存, 當你再次回到該項的時候, fragment會重建新實例, 並且狀態被恢復. 所以這種adapter適用於項目個數不確定或的情況.

所以使用FragmentPagerAdapter的時候需要註意記憶體問題.

notifyDatasetChanged()的問題.

notifyDataSetChanged()是用來處理數據集變化的情況, 比如一些項目增刪的情況. 這個方法不是用來刷新當前顯示的Fragment或其中的Views的.

文章中還有一些關於數據改變實現以及現有issue的討論. 為瞭解決issue作者還發佈了一個庫UpdatableFragmentStatePagerAdapter.

LIBRARIES & CODE

KeepActivitiesTile

一個quick settings tile來開啟"Don't keep activities".

WaveLoading

一個波形的loading圖, 水面上漲代表loading程度.

coordinators

Simple MVWhatever for Android.

epoxy

一個處理複雜的RecyclerView屏的庫.

Screen Record for Android

錄屏腳本.



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 搭建環境:Centos6.5_x86_64,Zabbix2.4.5,epel 源 服務端: 1.安裝開發軟體包yum -y groupinstall "Development Tools" 2.安裝所需的依賴包yum -y install httpd mysql mysql-server mysql ...
  • ...
  • 原型設計模式: 用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。 原型設計模式簡單的來說,顧名思義, 不去創建新的對象進而保留原型的一種設計模式。 缺點:原型設計模式是的最主要的缺點就是這個克隆方法需要對類的功能進行檢測,這對於全新的類來說較容易,但對已有的類進行改造時將不是件容易的 ...
  • 轉自:http://www.jb51.net/article/42671.htm 在開始之前先說一點,DOM是非常容易理解的,但是大家說的太官方,讓人很是難於理解,我們就用非常簡單的語言翻譯一遍。加深對DOM的理解,從而對它有一個全面的認識。 什麼是DOM DOM的全稱是Document Objec ...
  • 謹記(指定選擇器Intent.createChooser()) 開始今天的內容前,先閑聊一下: (1)突然有一天頭腦風暴,對很多問題有了新的看法和見解,迫不及待的想要分享給大家,文檔已經寫好了,我需要通過微信或者QQ,簡訊等社交工具發送給大家。 (2)在網上發現一段特別好的文章,想要保存收藏下來。 ...
  • 谷歌並沒有給出沉浸式狀態欄這個概念,谷歌只說了沉浸式模式(Immersive Mode)。 ...
  • ionic第二坑——ionic 上拉菜單(ActionSheet)安卓樣式坑 ...
  • 最近有個需求,需要做兩個功能相似的APP,大部分代碼是一樣的,只是界面不一樣,以前要維護兩套代碼,比較麻煩,最近在網上找資料,發現可以用gradle使用同一套代碼構建兩個APP。下麵介紹使用方法: 首先要構建兩個APP需要有兩個APP圖標、APP名字和AndroidManifest.xml。Andr ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...