Flutter 相機(jī)定制

Flutter中與硬件相關(guān)的部分,一直都挺蛋疼的。方案基本上有兩種,自己寫,或者等出相關(guān)的庫。

最近做的一個(gè)項(xiàng)目中,需要對(duì)相機(jī)做定制。有過相關(guān)模塊開發(fā)經(jīng)驗(yàn)的,就知道這種需求并不簡(jiǎn)單,況且是這種跨平臺(tái)解決方案的初期。

需求來了,怎么辦呢?那就只能硬著頭皮上了。先去pub上找找,有沒有可以使用的庫。初步挑到兩個(gè)庫,一個(gè)camera,另一個(gè)是image_picker。

image_picker試了下,基本上就pass了,只能調(diào)用系統(tǒng)相機(jī)或者選擇相冊(cè),相機(jī)相關(guān)部分,肯定是沒法使用。相冊(cè)部分倒是可以拿來使用。

camera試著運(yùn)行了下demo,感覺這個(gè)庫可以使用,直接將相機(jī)預(yù)覽封裝成一個(gè)flutter widget。我們可以很方便的在上面進(jìn)行各種定制。

設(shè)計(jì)圖上需要相機(jī)全屏顯示,試著在demo上修改成全屏,悲劇出現(xiàn)了,風(fēng)一般的拉伸效果。添加一個(gè)調(diào)取相機(jī)的頁面,在退出相機(jī)頁面后,demo置后臺(tái),切換到前臺(tái)的時(shí)候,Android這邊crash了,試了N多次,100%的crash,我勒個(gè)擦,谷歌官方的插件寫的這么隨意~

然后,重點(diǎn)來了,本文主要是解決這兩個(gè)問題,一個(gè)是全屏顯示的問題,另一個(gè)則是crash問題。

先上一張Android端的拍照效果圖:

Flutter 相機(jī)定制

Android端全屏拉伸問題

對(duì)于這種相機(jī)拉伸問題,做過相機(jī)定制相關(guān)的,都會(huì)知道是預(yù)覽的分辨率選擇錯(cuò)誤導(dǎo)致的,知道這一點(diǎn)過后,修改起來就簡(jiǎn)單的多了。直接拉camer plugin的源碼,Android的實(shí)現(xiàn),相對(duì)還是比較簡(jiǎn)單,一個(gè)文件700來行代碼。找到計(jì)算預(yù)覽尺寸的方法。

    private void computeBestPreviewAndRecordingSize(
        StreamConfigurationMap streamConfigurationMap, Size minPreviewSize, Size captureSize) {
        ....
    }

考慮到以后camera插件升級(jí)的問題,直接單獨(dú)新建一個(gè)文件進(jìn)行最佳預(yù)覽尺寸的計(jì)算,然后在調(diào)用處進(jìn)行替換即可。

Android端前后臺(tái)切換必現(xiàn)crash問題

Android端前后臺(tái)切換的問題,查看log發(fā)現(xiàn)是resume過后崩潰的,直接擼源代碼,發(fā)現(xiàn)插件監(jiān)聽了Activity的生命周期,在resume的時(shí)候進(jìn)行了open操作。

  @Override
  public void onActivityResumed(Activity activity) {
    if (requestingPermission) {
      requestingPermission = false;
      return;
    }
    if (activity == CameraPlugin.this.activity) {
      if (camera != null) {
        camera.open(null);
      }
    }
  }

問題來了,關(guān)鍵是,插件沒有進(jìn)行unregister操作,在退出相機(jī)頁面過后,調(diào)用dispose方法,會(huì)將camera關(guān)閉,并且將cameraDevice置為null,其他生命周期回調(diào)中調(diào)用cameraDevice的都會(huì)crash。onActivityResumed調(diào)用camer.open也會(huì)crash。這些crash的根本原因是因?yàn)闆]有將回調(diào)unregister掉。了解這些過后,修改起來就簡(jiǎn)單了,在dispose的時(shí)候,將插件的生命周期回調(diào)給unregister掉。修改完成后,試下效果,果然都沒有crash。

后話

相關(guān)代碼段我就不貼出來了,關(guān)于全屏預(yù)覽尺寸的計(jì)算,網(wǎng)上太多的資料了,將previewSize計(jì)算正確即可。第二個(gè)crash的問題,添加一個(gè)unregisterActivityLifecycleCallbacks即可。對(duì)于修改的地方,做好注釋,后續(xù)升級(jí)插件合入的時(shí)候不錯(cuò)亂即可。

目前來看Flutter第三方真的很差,如果只是自己個(gè)人項(xiàng)目,或者一些偏向于數(shù)據(jù)展示的項(xiàng)目,可以試一下。但是對(duì)于商業(yè)項(xiàng)目,尤其是硬件依賴性比較強(qiáng)的,還是建議一段時(shí)間過后再看看。

大后話

谷歌官方的camera插件,如果只是自己使用的話,可以按照上面的方法去修改,如果想要用在商業(yè)項(xiàng)目上,還是勸三思。

谷歌官方camera插件Android部分,用的是camera2 API,這個(gè)API有什么問題呢?

  1. 從21開始支持,也就是說需要放棄百分之十幾的份額;
  2. 上面版本不是最坑的,最坑的是什么呢?硬件廠商對(duì)camera2的支持程度,遇到幾臺(tái)機(jī)子,對(duì)camera2支持非常差,這些機(jī)子還是近一年比較新的機(jī)子(vivo x20a),獲取到的最大預(yù)覽分辨率非常低,拍出來的圖片尺寸也對(duì)不上。

最后,重寫了Android部分,直接采用camera API,支持版本從16開始,完全沒啥問題,對(duì)硬件支持也都非常完美。谷歌這個(gè)坑埋的有點(diǎn)深,最開始考慮時(shí)間因素,結(jié)果花在插件上修改分辨率、修改crash、排查特殊機(jī)型問題的時(shí)間不少。

參考

  1. Android設(shè)備對(duì)新Camera2 API的支持問題:以華為M2為例
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,034評(píng)論 25 709
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,203評(píng)論 3 119
  • 主持: 尊敬的紅姐,曉雨老師,親愛的悟我之心二期的伙伴們,大家早上好!時(shí)光匆匆,我們二期的踐行已來到了64天。在這...
    清晨的一抹朝霞閱讀 124評(píng)論 0 0
  • 一部關(guān)于生死情感的日本電影。 為什么離開的人要離開? “為了追逐生命中那一束美麗的光。" 從此,卸下了生命的重負(fù),...
    傲慢的小秋菊閱讀 301評(píng)論 0 1
  • 普文寺的早課鐘聲悠悠揚(yáng)揚(yáng)的在山里回響,不過是一夜,徽城的人都知道程府的大少爺出了家,嘆息之聲一直延伸到程府...
    甄弛閱讀 236評(píng)論 0 0

友情鏈接更多精彩內(nèi)容