bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

flutter共享,flutter共享元素

Flutter中InheritedWidget的使用

在Tree中從上往下高效傳遞數據的基類widget , 定義為:abstract class InheritedWidget extends ProxyWidget

站在用戶的角度思考問題,與客戶深入溝通,找到千山網站設計與千山網站推廣的解決方案,憑借多年的經驗,讓設計與互聯網技術結合,創造個性化、用戶體驗好的作品,建站類型包括:成都做網站、網站設計、企業官網、英文網站、手機端網站、網站推廣、申請域名網站空間、企業郵箱。業務覆蓋千山地區。

Flutter的響應式開發與React類似,數據都是自頂向下的。

假設有祖先組點A,中間經過結點B, C,然后到結點D,D需要從A中獲取數據f,那按照自頂向下數據流轉,f需要依次傳遞給B及C,最后才到C。這樣開發極為不靈活,成本也比較高。所有Flutter需要有跨結點(只能是祖先后代節點,不能跨兄弟節點)高效傳遞數據的方案。

大體意思如下:

InheritedWidget 是在樹中高效向下傳遞信息的基類部件;

調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例;

在 InheritedWidget 類型的控件被引用,也就是調用過 inheritFromWidgetOfExactType 方法后,當 InheritedWidget 自身狀態改變時,會導致引用了 InheritedWidget 類型的子控件重構(rebuild)。

這里隨便定義一個人 Person 類。

創建一個類繼承 InheritedWidget,并實現 updateShouldNotify 方法。

之前說到調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。

1.定義數據模型

這里隨便定義一個 Person 類。

2.自定義 InheritedWidget 控件類

創建一個類繼承 InheritedWidget,并實現 updateShouldNotify 方法。

之前說到調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。

3.InheriedDataWidget 的使用

InheriedDataWidget 使用起來也很簡單,它本身也是一個控件,只要在任意一個頁面的子控件調用其構造方法就行,這里我們定義一個形如的 Widget 樹。

WidgetA 是一個 StatefulWidget 類型的控件,可以調用 setState 刷新,如果是繼承人 Stateless 類型的控件,那我們也可以通過 Stream 或者其他方式刷新數據,感興趣的請看[什么是 Stream? Dart

WidgetA1_1 類

WidgetA1_2 類

WidgetA1_3 類

當我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次, 當我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次,都會輸出:

如果我們試圖在和 WidgetA 的同一層級的兄弟節點去訪問 InheriedDataWidget 的 Person 數據,是不行的,因為父節點中并沒有插入 InheriedDataWidget。

把 WidgetB 和 WidgetA 保持同一節點

這也體現了 Inheried(遺傳) 這一單詞的特性,遺傳只存在于父子。兄弟不存在遺傳的關系。

這種數據共享的方式在某些場景還是很有用的,就比如說全局主題,字體大小,字體顏色的變更,只要在 App 根層級共享出這些配置數據,然后在觸發數據改變之后,所有引用到這些共享數據的地方都會刷新,這換主題,字體是不是就很輕松,事實上 Theme.of(context).primaryColor 之流就是這么干的。

以上就是有關InheritedWidget的使用。

自己也是從事Android開發5年有余了;整理了一些Android開發技術核心筆記和面經題綱,有關更多Android開發進階技術資料、面經題綱、核心技術筆記; 想要進階自己、拿高薪的同學請私信我回復“核心筆記”或“面試”領取!

【Flutter】多組件共用狀態,父組件狀態傳遞給子組件

場景:多個組件共用一個狀態,子組件通過方法改變父組件狀態

思路:狀態和管理方法定義在父組件,通過構造函數傳遞給子組件

其他子組件按照同樣方法接收即可共用該父組件的狀態。

Flutter Android外接紋理實現圖片共享

Android 利用surface實現Flutter外接紋理

①Java層FlutterRenderer創建SurfaceTexture和textureId。

②將surfaceTexture和textureId通過JNI向引擎層注冊

③向引擎注冊過程中通過層層方法最后在texture.cc的TextureRegistry由map以鍵值對形式緩存實例對象。

④將需要顯示圖片在SurfaceTexture上離屏渲染。

⑤Java層創建的textureId通過Channel傳遞到Dart層作為Texture組件入參。

⑥Dart的Texture組件接收textureId入參后向下層組件實例化。

⑦在SceneBuilder調用addTexture時執行引擎層創建TextureLayer。

⑧最終在texture.cc中TextureRegistry的map根據TextureId獲取SurfaceTexture實例。

使用Native(以Android為例)播放器構建Flutter播放插件

iOS 實現Flutter外接紋理

Flutter浪潮下的音視頻研發探索

文/陳爐軍

整理/LiveVideoStack

大家好,我是阿里巴巴閑魚事業部的陳爐軍,本次分享的主題是Flutter浪潮下的音視頻研發探索,主要內容是針對閑魚APP在當下流行的跨平臺框架Flutter的大規模實踐,介紹其在音視頻領域碰到的一些困難以及解決方案。

分享內容主要分為四個方面,首先會對Flutter有一個簡單介紹以及選擇Flutter作為跨平臺框架的原因,其次會介紹Flutter中與音視頻關系非常大的外接紋理概念,以及對它做出的一些優化。之后會對閑魚在音視頻實踐過程中碰到的一些Flutter問題提出了一些解決方案——TPM音視頻框架。最后是閑魚Flutter多媒體開源組件的介紹。

Flutter

Flutter是一個跨平臺框架,以往的做法是將音頻、視頻和網絡這些模塊都下沉到C++層或者ARM層,在其上封裝成一個音視頻的SDK,供UI層的PC、iOS和Android調用。

而Flutter做為一個UI層的跨平臺框架,顧名思義就是在UI層也實現了一個跨平臺開發。可以預想的是未Flutter發展的好的話,會逐漸變為一個從底層到UI層的一個全鏈路的跨平臺開發,技術人員分別負責SDK和UI層的開發。

在Flutter之前已經有很多跨平臺UI解決方案,那為什么選擇Flutter呢?

我們主要考慮性能和跨平臺的能力。

以往的跨平臺方案比如Weex,ReactNative,Cordova等等因為架構的原因無法滿足性能要求,尤其是在音視頻這種性能要求幾乎苛刻的場景。

而諸如Xamarin等,雖然性能可以和原生App一致,但是大部分邏輯還是需要分平臺實現。

我們可以看一下,為什么Flutter可以實現高性能:

原生的native組件渲染以IOS為例,蘋果的UIKit通過調用平臺自己的繪制框架QuaztCore來實現UI的繪制,圖形繪制也是調用底層的API,比如OpenGL、Metal等。

而Flutter也是和原生API邏輯一致,也是通過調用底層的繪制框架層SKIA實現UI層。這樣相當于Flutter他自己實現了一套UI框架,提供了一種性能超越原生API的跨平臺可能性。

但是我們說一個框架最終性能怎樣,其實取決于設計者和開發者。至于現在到底是一個什么狀況:

在閑魚的實踐中,我們發現在正常的開發沒有特意的去優化UI代碼的情況下,在一些低端機上,Flutter界面的流暢性是比Native界面要好的。

雖然現在閑魚某些場景下會有卡頓閃退等情況,但是這是一個新事物發展過程中的必然問題,我們相信未來性能肯定不會成為限制Flutter發展的瓶頸的。

在閑魚實踐Flutter的過程中,混合棧和音視頻是其中比較難解決的兩個問題,混合棧是指一個APP在Flutter過程中不可能一口氣將所有業務全部重寫為Flutter,所以這是一個逐步迭代的過程,這期間原生native界面與Flutter界面共存的狀態就稱之為混合棧。閑魚在混合棧上也有一些比較好的輸出,例如FlutterBoost。

外接紋理

在講音視頻之前需要簡要介紹一下外接紋理的概念,我們將它稱之為是Flutter和Frame之間的橋梁。

Flutter渲染一幀屏幕數據首先要做的是,GPU發出的VC信號在Flutter的UI線程,通過AOT編譯的機器碼結合當前Dart Runtime,生成Layer Tree UI樹,Layer Tree上每一個葉子節點都代表了當前屏幕上所需要渲染的每一個元素,包含了這些元素渲染所需要的內容。將Layer Tree拋給GPU線程,在GPU線程內調用Skia去完成整個UI的渲染過程。Layer Tree中有PictureLayer和TextureLayer兩個比較重要的節點。PictureLayer主要負責屏幕圖片的渲染,Flutter內部實現了一套圖片解碼邏輯,在IO線程將圖片讀取或者從網絡上拉取之后,通過解碼能夠在IO線程上加載出紋理,交給GPU線程將圖片渲染到屏幕上。但是由于音視頻場景下系統API太過繁多,業務場景過于復雜。Flutter沒有一套邏輯去實現跨平臺的音視頻組件,所以說Flutter提出了一種讓第三方開發者來實現音視頻組件的方式,而這些音視頻組件的視頻渲染出口,就是TextureLayer。

在整個Layer Tree渲染的過程中,TextureLayer的數據紋理需要由外部第三方開發者來指定,可以把視頻數據和播放器數據送到TextureLayer里,由Flutter將這些數據渲染出來。

TextureLayer渲染過程:首先判斷Layer是否已經初始化,如果沒有就創建一個Texture,然后將Texture Attach到一個SufaceTexture上。

這個SufaceTexture是音視頻的native代碼可以獲取到的對象,通過這個對象創建的Suface,我們可以將視頻數據、攝像頭數據解碼放到Suface中,然后Flutter端通過監聽SufaceTexture的數據更新就可以順利把剛才創建的數據更新到它的紋理中,然后再將紋理交給SKIA渲染到屏幕上。

然而我們如果需要用Flutter實現美顏,濾鏡,人臉貼圖等等功能,就需要將視頻數據讀取出來,更新到紋理中,再將GPU紋理經過美顏濾鏡處理后生成一個處理后的紋理。按Flutter提供的現有能力,必須先將紋理中的數據從GPU讀出到CPU中,生成Bitmap后再寫入Surface中,這樣在Flutter中才能順利的更新到視頻數據,這樣做對系統性能的消耗很大。

通過對Flutter渲染過程分析,我們知道Flutter底層需要渲染的數據就是GPU紋理,而我們經過美顏濾鏡處理完成以后的結果也是GPU紋理,如果可以將它直接交給Flutter渲染,那就可以避免GPU-CPU-GPU這樣的無用循環。這樣的方法是可行的,但是需要一個條件,就是OpenGL上下文共享。

OpenGL

在說上下文之前,得提到一個和上線文息息相關的概念:線程。

Flutter引擎啟動后會啟動四個線程:

第一個線程是UI線程,這是Flutter自己定義的UI線程,主要負責GPU發出的VSync信號時候用當前Dart編譯的機器碼和當前運行環境創建出Layer Tree。

還有就是IO線程和GPU線程。和大部分OpenGL處理解決方案中一樣,Flutter也采取一個線程責資源加載,一部分負責資源渲染這種思路。

兩個線程之間紋理共享有兩種方式。一種是EGLImage(IOS是 CVOpenGLESTextureCache)。一種是OpenGL Share Context。Flutter通過Share Context來實現紋理共享,將IO線程的Context和GPU線程的Context進行Share,放到同一個Share Group下面,這樣兩個線程下資源是互相可見可以共享的。

Platform線程是主線程,Flutter中有一個很奇怪的設定,GPU線程和主線程共用一個Context。并且在主線程也有很多OpenGL 操作。

這樣的設計會給音視頻開發帶來很多問題,后面會詳細說。

音視頻端美顏處理完成的OpenGL紋理能夠讓Flutter直接使用的條件就是Flutter的上下文需要和平臺音視頻相關的OpenGL上下文處在一個Share Group下面。

由于Flutter主線程的Context就是GPU的Context,所以在音視頻端主線程中有一些OpenGL操作的話,很有可能使Flutter整個OpenGL被破壞掉。所以需要將所有的OpenGL操作都限制在子線程中。

通過上述這兩個條件的處理,我們就可以在沒有增加GPU消耗的前提下實現美顏和濾鏡等等功能。

TPM

在經過demo驗證之后,我們將這個方案應用到閑魚音視頻組件中,但改造過程中發現了一些問題。

上圖是攝像頭采集數據轉換為紋理的一段代碼,其中有兩個操作:首先是切進程,將后面的OpenGL操作都切到cameraQueue中。然后是設置一次上下文。然后這種限制條件或者說是潛規則往往在開發過程中容易被忽略的。而這個條件一旦忽略后果就是出現一些莫名其妙的詭異問題極難排查。因此我們就希望能抽象出一套框架,由框架本身實現線程的切換、上下文和模塊生命周期等的管理,開發者接入框架以后只需要安心實現自己的算法,而不需要關心這些潛規則還有其他一些重復的邏輯操作。

在引入Flutter之前閑魚的音視頻架構與大部分音視頻邏輯一樣采用分層架構:

1:底層是一些獨立模塊

2:SDK層是對底層模塊的封裝

3:最上層是UI層。

引入Flutter之后,通過分析各個模塊的使用場景,我們可以得出一個假設或者說是抽象:音視頻應用在終端上可以歸納為視頻幀解碼之后視頻數據幀在各個模塊之間流動的過程,基于這種假設去做Flutter音視頻框架的抽象。

咸魚Flutter多媒體開源組件

整個Flutter音視頻框架抽象分為管線和數據的抽象、模塊的抽象、線程統一管理和上下文同一管理四部分。

管線,其實就是視頻幀流動的管道。數據,音視頻中涉及到的數據包括紋理、Bit Map以及時間戳等。結合現有的應用場景我們定義了管線流通數據以Texture為主數據,同時可以選擇性的添加Bit Map等作為輔助數據。這樣的數據定義方式,避免重復的創建和銷毀紋理帶來的性能開銷以及多線程訪問紋理帶來的一些問題。也滿足一些特殊模塊對特殊數據的需求。同時也設計了紋理池來管理管線中的紋理數據。

模塊:如果把管線和數據比喻成血管和血液,那框架音視頻的場景就可以比喻成器官,我們根據模塊所在管線的位置抽象出采集、處理和輸出三個基類。這三個基類里實現了剛才說的線程切換,上下文切換,格式轉換等等共同邏輯,各個功能模塊通過集成自這些基類,可以避免很多重復勞動。

線程:每一個模塊初始化的時候,初始化函數就會去線程管理的模塊去獲取自己的線程,線程管理模塊可以決定給初始化函數分配新的線程或者已經分配過其他模塊的線程。

這樣有三個好處:

一是可以根據需要去決定一個線程可以掛載多少模塊,做到線程間的負載均衡。第二,多線程并發式能夠保證模塊內的OpenGL操作是在當前線程內而不會跑到主線程去,徹底避免Flutter的OpenGL 環境被破壞。第三,多線程并行可以充分利用CPU多核架構,提升處理速度。

從Flutter端修改Flutter引擎將Context取出后,根據Context創建上下文的統一管理模塊,每一個模塊在初始化的時候會獲取它的線程,獲取之后會調用上下文管理模塊獲取自己的上下文。這樣可以保證每一個模塊的上下文都是與Flutter的上下文進行Share的,每個模塊之間資源都是共享可見的,Flutter和音視頻native之間也是互相共享可見的。

基于上述框架如果要實現一個簡單的場景,比如畫面實時預覽和濾鏡處理功能,

1:需要選擇功能模塊,功能模塊包括攝像頭模塊、濾鏡處理模塊和Flutter畫面渲染模塊,

2:需要配置模塊參數,比如采集分辨率、濾鏡參數和前后攝像頭設置等,

3:在創建視頻管線后使用已配置的參數創建模塊

4:最后管線搭載模塊,開啟管線就可以實現這樣簡單的功能。

上圖為整個功能實現的代碼和結構圖。

結合上述音視頻框架,閑魚實現了Flutter多媒體開源組件。

組要包含四個基本組件分別是:

1:視頻圖像拍攝組件

2:播放器組件

3:視頻圖像編輯組件

4:相冊選擇組件

現在這些組件正在走內部開源流程。預計9月份,相冊和播放器會實現開源。

后續展望和規劃

1:實現開頭所說的從底層SDK到UI的全鏈路的跨端開發。目前底層框架層和模塊層都是各個平臺各自實現,反而是Flutter的UI端進行了跨平臺的統一,所以后續會將底層也按照音視頻常用做法把邏輯下沉到C++層,盡可能的實現全鏈路跨平臺。

2:第二部分內容為開源共建,閑魚開源的內容不僅包括拍攝、編輯組件,還包括了很多底層模塊,希望有開發者在基于Flutter開發音視頻應用時可以充分利用閑魚開源出的音視頻模塊能力,搭建APP框架,開發者只要去負責實現特殊需求模塊就可以,盡可能的減少重復勞動。

flutter 如何實現app與打印機連接打印文件?

點擊開始----控制版面-----打印機和傳真機----點擊添加打印機----在彈出的添加打印機向導對話框中點下一步----選第一項本地打印機再點下一步----下一步直到出現廠商一欄時,點擊從磁盤安裝.再將你的打印機驅動放入光驅中..向下就行了

右鍵單擊要共享的打印機,然后單擊“共享”。 根據計算機上是否啟用了共享,在“共享”選項卡上的選項會各不相同。要了解下一步怎么做,請在“共享”選項卡上單擊有相應說明的選項。 一條消息提示打印機共享必須打開 需要運行“網絡安裝向導”,以啟用打印機共享。首先單擊“共享”選項卡上的鏈接,然后執行系統指示以啟動共享。一旦啟用了共享,請再次執行該過程。 顯示共享或不共享打印機的選項 在“共享”選項卡上,單擊“共享這臺打印機”,然后在“共享名”框中鍵入共享打印機的名稱。 如果與硬件或操作系統不同的用戶共享打印機,請單擊“其他驅動程序”。單擊其他計算機的環境和操作系統,然后單擊“確定”,以安裝其他驅動程序。 運行 Windows 其他版本(Windows 95、Windows 98 或者 Windows NT 4.0)的用戶可在支持 CD 中找到驅動程序。但其中沒有 Windows NT 3.1 和 Windows NT 3.5 的打印機驅動程序。 單擊“確定”。如果已經安裝了其他驅動程序,則單擊“關閉”。 如果已遵循上述步驟,但仍無法共享打印機,那么請打開 Windows 防火墻。(要打開“Windows 防火墻”,請依次單擊“開始”、“控制面板”,然后雙擊“Windows 防火墻”。) 然后,在“例外”選項卡上,選擇“文件和打印機共享”復選框。 注意 要打開“打印機和傳真”,請依次單擊“開始”、“控制面板”,然后雙擊“打印機和傳真”。 還可以在“打印機和傳真”中共享打印機,方法是:單擊要共享的打印機,然后單擊左側窗格“打印機任務”下面的“共享此打印機”。只有當文件夾設置為網頁風格,并且當前選中打印機時,該選項才可用。詳細信息,請單擊“相關主題”。 默認情況下,當打印機安裝在 Windows XP Professional 上時打印機沒有共享,但可以選擇將安裝在計算機上的任何打印機共享。 當在 Active Directory 中發布打印機后,登錄到 Windows 域的其他用戶可以根據打印機的位置和特性(諸如每分鐘打印多少頁、是否支持彩色打印等)來搜索打印機。

標題名稱:flutter共享,flutter共享元素
文章源于:http://vcdvsql.cn/article2/dsijdoc.html

成都網站建設公司_創新互聯,為您提供面包屑導航做網站用戶體驗營銷型網站建設Google電子商務

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都app開發公司