這是我最近一年在做的項目,用我們老大的話說,就是「能不能弄一個東西,讓我的 iOS 程序一行代碼不用改,卻能運行在 Android 上」。為了這個目標,我們最後弄出了個這樣的東西。
說起來我們之所以要做這個東西也是蠻有趣的。事情的起因,我們需要把一個為 iOS 寫的排版引擎移植到 Android 上。但我們覺得這個排版引擎實在是太複雜了,而且把一個寫好的 iOS 程序重新寫個 Android 版本很無趣,那就變成了跟抄作業一樣把 Objective-C 代碼換成 Java 代碼的行為了。
於是,為了移植這個排版引擎,我們面臨兩個選擇:
最終,我們選擇了 2,於是我今後的一年(至今)就在搞這個東西了。
談談我個人的體會吧。我參與到這個項目之後,就真正體會到了 iOS 的博大精深。我之前當然知道 iOS 一定有很多很多東西,但是當真正參與了這個項目,才發現 iOS 居然是如此的龐大。以至於它的一個小小的方面居然就包含了那麼多東西。
我本人的工作主要是把 Cocoa Touch 層移植到 Android 上去。具體就是如圖:
把最上面那個青藍色的方塊移植到 Android 上去。順便一提,iOS 的很多庫是和 Mac 共用的。Apple 會用開源項目,Apple 自己閉源的東西會被別人開源。因此,如果是有歷史的庫,而且和 Mac 共用的庫,一般都有開源項目可利用。但是 Cocoa Touch 層就比較坑爹,幾乎沒有可用的開源項目可直接使用。
於是,我本人的工作就是,手寫 Cocoa Touch 層的代碼,這個工作花了大概一年的時間。
某種意義上,我的任務性質有點像逆向推導出 Cocoa Touch 的內容。我需要查閱 Apple 的 API 文檔,對文檔的閱讀要到細緻到每個單詞。然後給 h 文件填充實現,實現內容和 Apple 的程式設計師的實現越接近越好。但有一件事是 Apple 的程式設計師絕對不會做但我會做的,我還需要通過 JNI 調用 Android 的 API,並用 Java 編寫一些功能讓 Objective-C 使用。總之,至少在 Cocoa Touch 層這裡,我要騙目標代碼說它是在 iOS 上運行,而不能讓它發現其實它是在 Android 上運行。
這個工作最麻煩的地方其實並不是在於「寫出一個 Cocoa Touch 層」。光是寫個 Cocoa Touch 是很簡單的。難點在於,我手頭能拿到的只有 Apple 的 API 文檔以及和 h 文件。但是 API 文檔給出的細節並不充足,這也可以理解,因為 API 文檔是給開發 iOS 的開發者看的,可不是給我這種人看的。
因此,令人頭疼的地方在於,針對具體實現,很多狀態是隱藏的,也沒有必要讓 iOS 開發者知道這些狀態,因此這些細節也絕對別想在 Apple 的 API 文檔裡找到。但是我必須知道這些細節,如果不知道這些細節,或者我自己寫個實現有偏差的東西,到了 Android 上跑後會看到巨大的差異,而且這種差異極其難以定位。我這麼說可能難以理解(恕我表達能力有限),總之就是「差之毫厘謬以千裡」這樣子。
這種定位的困難如果處理不當,對進度影響是很惡劣的。因為 bug 出現的地方可能和實際暴露的點之間隔了好多層呢。可能涉及到排版引擎的代碼、各種開源項目的代碼、我本人寫的代碼等。你要把 bug 和出問題的地方聯繫起來,不把整個項目拆了是做不到的。這種事情出一次,你也許得浪費 3、4 天時間來收拾。
而且更棘手的地方在於,如果你處理不好,這種現象可能每天都會冒出來。如果連續出個10幾個,你就只能自殺了。幸運的是,我真的有認真考慮過這些可能性,並作了一些措施,結果,這一年裡這種事情只出過幾次。(但這幾次就夠嗆了。)
這種問題經過我摸索,基本上靠兩種方法解決。
第一,建立假設模型,然後實驗。通過實驗結果獲取反饋,或者修改模型,或者證實模型。模型一旦證實,就可以開始碼代碼了。
第二,做實驗可以獲得大部分細節,但是某些太細節的東西做實驗也沒法活的。就只好先實現一個版本,然後假設它沒有太大問題,等到之後證實有問題再改。
後一種情況比較坑爹,有些問題需要 3 個月才能暴露。將 3 個月後出現的問題與 3 個月之前寫的代碼聯繫起來是一件很頭疼的事情。好在我 git 操作還算熟練。
對比起之前在另一家公司寫業務邏輯代碼的 Debug 過程,簡直不要太輕鬆。有強大的 IDE,加上僅僅通過設置斷點和列印日誌就能發現 bug,簡直太美好了。
現在,我們的排版引擎已經能順利在 Android 上運行了。
你能想像,你用 MacBook 接上一臺 Android 平板和一臺 iPad,然後在 Xcode 按一個按鈕,你的 Android 平板和 iPad 會同時打開一個相同的 App。目前我們就能達到這種程度。
不過很遺憾的是,我們的團隊恐怕過幾個月後就要解散了。雖然這個項目還有很多工作可以繼續做,但是我們的團隊恐怕不會繼續做它了。以後可能會把它開源吧。
順便推銷一下我自己:
本人 2014 年畢業,快 2 年工作經驗,過去 1 年遠程工作經驗
優先考慮遠程工作
我的郵箱:xiangtantaozeyu@icloud.com
微信號:xiangtan_tao
原載:segmenfault