Facebook YOGA初探:跨平臺(tái)的布局引擎(基于Android)

YOGA簡介

Facebook引領(lǐng)著移動(dòng)開源風(fēng)向,這次它對(duì)布局出手了东囚,推出了Yoga開源項(xiàng)目,意在打造一個(gè)跨iOS战授、Android页藻、Windows平臺(tái)在內(nèi)的布局引擎桨嫁,兼容Flexbox布局方式,讓界面布局更加簡單份帐。

Yoga官網(wǎng):https://facebook.github.io/yoga/

官網(wǎng)上描述的特性包括:

  • 完全兼容Flexbox布局璃吧,遵守W3C的規(guī)范

  • 支持Java、C#废境、Objective-C肚逸、C四種語言

  • 底層代碼使用C語言編寫,性能不是問題

  • 支持流行框架如React Native

背景

目前彬坏,各個(gè)平臺(tái)都有自己的一套解決方案朦促。iOS平臺(tái)有AutoLayout,Android有容器布局系統(tǒng)栓始,而Web端有基于CSS的布局系統(tǒng)务冕。多種布局系統(tǒng)共存所帶來的弊端是很明顯的,平臺(tái)間的共享變得很困難幻赚,而每個(gè)平臺(tái)都需要專人來開發(fā)維護(hù)禀忆,增加了開發(fā)成本。

像微信小程序落恼、ReactNative這種箩退,都是采用js/html/css開發(fā),客戶端native展現(xiàn)的方式佳谦,那如何把前端的布局對(duì)應(yīng)到Android/iOS的不同平臺(tái)上戴涝?

微信小程序、ReactNative都是怎么來實(shí)現(xiàn)的钻蔑?

YOGA就是為了解決這樣的問題產(chǎn)生的啥刻。

在React Native里Facebook里引入了一種跨平臺(tái)的基于CSS的布局系統(tǒng),它實(shí)現(xiàn)了Flexbox規(guī)范咪笑】擅保基于這個(gè)布局系統(tǒng),不同團(tuán)隊(duì)終于可以走到一起窗怒,一起解決缺陷映跟,改進(jìn)性能,讓這個(gè)系統(tǒng)更加地貼合Flexbox規(guī)范扬虚。隨著這個(gè)系統(tǒng)的不斷完善努隙,F(xiàn)acebook決定對(duì)它進(jìn)行重啟發(fā)布,并取名Yoga孔轴。

Yoga是基于C實(shí)現(xiàn)的剃法。之所以選擇C,首先當(dāng)然是從性能方面考慮的〈蓿基于C實(shí)現(xiàn)的Yoga比之前Java實(shí)現(xiàn)在性能上提升了33%收厨。其次,使用C實(shí)現(xiàn)可以更容易地跟其它平臺(tái)集成优构。到目前為止诵叁,Yoga已經(jīng)有以下幾個(gè)平臺(tái)的綁定:Java(Android)、Objective-C(UIKit)钦椭、C#(.NET)拧额。而且已經(jīng)有很多項(xiàng)目在使用Yoga,比如React Native彪腔、Components for Android侥锦、Oculus,等等德挣。

不同于其它的一些布局框架恭垦,比如bootstrap的柵格系統(tǒng)或Masonry,它們要么不夠強(qiáng)大格嗅,要么不支持跨平臺(tái)番挺。Yoga遵循了Flexbox規(guī)范,同時(shí)又將布局元素抽象成Node屯掖,為各個(gè)不同平臺(tái)暴露出一組標(biāo)準(zhǔn)的接口玄柏,這樣不同的平臺(tái)只需實(shí)現(xiàn)這些接口就可以了。

當(dāng)然贴铜,F(xiàn)acebook不會(huì)就此止步粪摘。作為一款跨平臺(tái)的布局引擎,自然需要各個(gè)平臺(tái)的開發(fā)人員一起努力來促進(jìn)它的發(fā)展阀湿,所以Facebook把Yoga開源了赶熟。目前微軟已經(jīng)成為Yoga的貢獻(xiàn)者之一,他們不僅修復(fù)缺陷陷嘴,還為Yoga帶來新的特性。

除了完全遵循Flexbox規(guī)范间坐,F(xiàn)acebook還計(jì)劃在未來為Yoga加入更多特性灾挨,這些特性將超出Flexbox的范疇。

應(yīng)用展望

從目前為止竹宋,困擾客戶端的一大問題就是Android/iOS完全不同的布局系統(tǒng)劳澄,對(duì)于Android來說復(fù)雜的布局必須使用xml來描述,而xml不能動(dòng)態(tài)發(fā)布的特性蜈七,也完全限制了客戶端view的展現(xiàn)秒拔,試想一下,如果能把Android/iOS的布局統(tǒng)一飒硅,并且可以根據(jù)下發(fā)的布局配置實(shí)時(shí)生成動(dòng)態(tài)的布局砂缩,豈不是很爽作谚!

利用YOGA我們可以

  • 只寫一次布局,就可以得到在不同端上的布局展示庵芭。
  • 動(dòng)態(tài)更改view的布局
  • 還有各種意義妹懒。。双吆。

總的來說眨唬,大前端的趨勢(shì)越發(fā)明顯

YOGA初探

當(dāng)?shù)弥猋OGA開源的消息時(shí),樓主第一時(shí)間去github上看了源代碼好乐,F(xiàn)acebook提供了iOS和Windows的sample工程匾竿,唯獨(dú)沒有提供Android的example,只有一個(gè)Java庫的代碼蔚万,于是樓主在想既然源碼都有岭妖,那寫一個(gè)Android的example,于是就動(dòng)起手來笛坦,最后終于把YOGA集成在了Android的工程上区转,并順利跑通。具體過程如下版扩。

生成so

YOGA是基于C實(shí)現(xiàn)的废离,因此我們的思路很明確,就是把YOGA的C代碼交叉編譯成可在
Android上運(yùn)行的so礁芦。這里我們需要用到BUCK,因?yàn)閅OGA是基于BUCK構(gòu)建的蜻韭,BUCK可以理解成是和Gradle一樣的構(gòu)建工具,這里有一個(gè)關(guān)于Gradle和Buck的構(gòu)建速度對(duì)圖:

要得到android-armv7的so柿扣,需要交叉編譯肖方,我們需要確保本地已經(jīng)安裝了Android NDK的環(huán)境,可以參考Android 官網(wǎng)未状。

通過分析YOGA工程的BUCK配置俯画,發(fā)現(xiàn)YOGA由3個(gè)模塊組成,分布在三個(gè)地方司草,分別是:

  • libyogacore.so 在/yoga目錄下
  • libyouga.so 在/java/jni目錄下
  • liblib_fb_fbjni.so 在/lib/fb 目錄下

我們只要執(zhí)行BUCK的構(gòu)建代碼艰垂,就可以生成上面提到的三個(gè)so,構(gòu)建代碼如下:

$ buck build //java:jni#android-armv7,shared

這里有坑埋虹,編譯時(shí)我們需要兩個(gè)flavor猜憎,分別是android-armv7shared

  • android-armv7 就是支持armeabi架構(gòu)的.so文件,這里需要有NDK環(huán)境的支持
  • shared 就是生成動(dòng)態(tài)鏈接庫

因?yàn)樯危绻覀冎苯邮褂媚J(rèn)的構(gòu)建配置

$ buck build

會(huì)發(fā)現(xiàn)胰柑,生成的不是動(dòng)態(tài)鏈接庫so,而是靜態(tài)鏈接庫,而且也不是基于android-armv7生成的so柬讨,所以需要指定編譯的platform和明確要編譯的是動(dòng)態(tài)鏈接庫崩瓤,才能生成可用的so.

當(dāng)完成上面的步驟之后,我們還會(huì)發(fā)現(xiàn)一個(gè)問題姐浮,就是當(dāng)你的工程在加載so的時(shí)候谷遂,會(huì)報(bào)錯(cuò):

can't find  libgnustl_shared.so 

這時(shí)我們需要把ndk目錄下的 libgnustl_shared.so 也拷貝到工程目錄下,路徑如下:

android-ndk-r13b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a

為什么會(huì)有這樣的

創(chuàng)建Android工程

在生成so之后卖鲤,后面的步驟大家應(yīng)該很清楚了肾扰,把生成的so放在Android目錄下的jniLibs下,并把YOGA中的java庫引入工程蛋逾,一個(gè)完整的可以運(yùn)行YOGA的Android工程就創(chuàng)建好了集晚。

sample

目前寫了一個(gè)很簡單的用YOGA實(shí)現(xiàn)的布局,首先我們用基于Flexbox的規(guī)范來布局view区匣,然后調(diào)用root.calculateLayout() 就可以得到在Android下的view的坐標(biāo)偷拔、長、寬等基本布局信息,代碼如下:

            YogaNode root = new YogaNode();
            root.setWidth(500);
            root.setHeight(300);
            root.setAlignItems(YogaAlign.CENTER);
            root.setJustifyContent(YogaJustify.CENTER);
            root.setPadding(YogaEdge.ALL, 20);

            YogaNode text = new YogaNode();
            text.setWidth(200);
            text.setHeight(25);

            YogaNode image = new YogaNode();
            image.setWidth(50);
            image.setHeight(50);
            image.setPositionType(YogaPositionType.ABSOLUTE);
            image.setPosition(YogaEdge.END, 20);
            image.setPosition(YogaEdge.TOP, 20);

            root.addChildAt(text, 0);
            root.addChildAt(image, 1);

            root.calculateLayout();

            Log.d(TAG,"text,layout X:"+text.getLayoutX()+" layout Y:"+text.getLayoutY());
            Log.d(TAG,"image,layout X:"+image.getLayoutX()+" layout Y:"+image.getLayoutY());

工程

目前我把基于YOGA的Android工程已傳到github亏钩,歡迎各位多多交流莲绰,多給star。Thanks!
地址:https://github.com/koudle/AndYogaSample

文章參考:

https://facebook.github.io/yoga/
https://buckbuild.com/
http://mp.weixin.qq.com/s/VT6uytG8di-KNfJDCZE5Og

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末姑丑,一起剝皮案震驚了整個(gè)濱河市蛤签,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌栅哀,老刑警劉巖震肮,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異留拾,居然都是意外死亡戳晌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門痴柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沦偎,“玉大人,你說我怎么就攤上這事咳蔚】甘” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵屹篓,是天一觀的道長。 經(jīng)常有香客問我匙奴,道長堆巧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮谍肤,結(jié)果婚禮上啦租,老公的妹妹穿的比我還像新娘。我一直安慰自己荒揣,他們只是感情好篷角,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著系任,像睡著了一般恳蹲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俩滥,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天嘉蕾,我揣著相機(jī)與錄音,去河邊找鬼霜旧。 笑死错忱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挂据。 我是一名探鬼主播以清,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼崎逃!你這毒婦竟也來了掷倔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤婚脱,失蹤者是張志新(化名)和其女友劉穎今魔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體障贸,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡错森,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了篮洁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涩维。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖袁波,靈堂內(nèi)的尸體忽然破棺而出瓦阐,到底是詐尸還是另有隱情,我是刑警寧澤篷牌,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布睡蟋,位于F島的核電站,受9級(jí)特大地震影響枷颊,放射性物質(zhì)發(fā)生泄漏戳杀。R本人自食惡果不足惜该面,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望信卡。 院中可真熱鬧隔缀,春花似錦、人聲如沸傍菇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丢习。三九已至牵触,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泛领,已是汗流浹背荒吏。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渊鞋,地道東北人绰更。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像锡宋,于是被迫代替她去往敵國和親儡湾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容