13、最新安卓Xamarin繫結相關填坑之旅
今天群裡面有兄弟夥說第三方庫用不起。說實話在我覺得第三方庫能成功的機率大於90% 除了極少數噁心的庫以外。
絕大部分第三方庫都還是可以繫結好的
這個是官方的也有對應的demo
首先遇到繫結庫 我會第一時間nuget查詢下 雖然這種庫很少有人會用。但是萬一有人綁定了呢?
然後 我會在github搜尋下有木有好心的人綁定了
這2個方法後都沒得人繫結 好吧 那就我自己開擼
首先安卓的繫結絕對比ios繫結容易得多 耐心細心慢慢來肯定可以解決
先下載官方的 用as開啟跑起來 沒問題 好的 官方無坑。 (一定記得這一步 不然萬一官方的有坑你自己又在擼會哭的)
接下來 準備一個2個工具 ILSpy.exe Jd-gui.exe
然後先看下官方依賴的庫有那些 這一步很重要
用相關的gradlew 去檢視相關依賴 具體百度 Android Studio 依賴檢視
目前我查出來依賴了
systemweb-2.0.9
sdk-analytics-0.4.7
youzansdk-6.3.5
anko-commons-0.10.0
anko-sqlite-0.10.0
gson-2.8.0
okhttp-3.8.1
okio-1.13.0
basic-6.3.5
webcache-2.2.0
jsbridge-2.0.2
這裡面如果是aar 記得要單獨建一個繫結類庫
開始繫結
第一步繫結basic-6.3.5 .aar 的時候就發現有個YouzanBrowser類無法生成 這個時候 開啟
檢視所有檔案
開啟這個資料夾 然後檢視 裡面有個 classs.jar 用jd-gui.exe 工具反編譯檢視下類的結構
然後用xml語法進行編輯修改 請記住 官方的自動生成只是簡化這個步驟而已. 對寫得很好的庫完全沒問題 但是有些國內廠商寫得並不好 一堆亂 意味著你就放棄掉這些好了 直接自己來寫
首先remove-node 移除掉編譯出錯的節點
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
語法是 xpath 語法 操作的物件是什麼物件呢? 是一個xml檔案
api.xml 是工具幫你生成的 有時候你記不住語法 可以參考下
api.xml.fixed 是經過修改後生成的(經過你的xpath處理 也就是一直在說的Metadata.xml 檔案)
好了 其他都不重要 記住 如果你發現編譯一堆語法錯誤 首先 直接remove掉這些節點和錯誤的類
然後根據專案需要那些api方法和類 直接自己生成
我們需要YouzanBrowser 這個物件 用jd-gui開啟對應的class.jar
這不是我們需要的類嗎?為什麼生成不了? 大部分都是因為依賴的第三方庫 第三方的類和物件無法解析 介面實現等 都會有這個問題。我們不管先看下
塗抹的內容不重要
只看一個Package class名字 繼承關係
<add-node path="/api/package[@name='com.youzan.androidsdk.basic']"> <class abstract="false" deprecated="not deprecated" extends="android.webkit.WebView" extends-generic-aware="java.lang.Object" final="false" name="YouzanBrowser" static="false" visibility="public"> </class> </add-node>
這裡面的名字 大家英文好 看看就行 需要注意的是2個東西
extends 如果沒有特殊的需要可以不用繼承特定的型別 直接繼承Object 即可 但是我們這裡由於需要一個特定型別的 在程式碼裡面 所以設定他繼承 android.webkit.WebView 具體的型別大家可以看他jd-gui 的原始碼
然後就是新增需要的方法
<constructor deprecated="not deprecated" final="false" name="YouzanBrowser" static="false" visibility="public"> <parameter name="context" type="android.content.Context"> </parameter> </constructor> <method abstract="false" deprecated="not deprecated" final="false" name="pageGoBack" native="false" return="boolean" static="false" synchronized="false" visibility="public"> </method> <method abstract="false" deprecated="not deprecated" final="false" name="reload" native="false" return="void" static="false" synchronized="false" visibility="public"> </method> <method abstract="false" deprecated="not deprecated" final="false" name="onPause" native="false" return="void" static="false" synchronized="false" visibility="public"> </method> <method abstract="false" deprecated="not deprecated" final="false" name="destroy" native="false" return="void" static="false" synchronized="false" visibility="public"> </method> <method abstract="false" deprecated="not deprecated" final="false" name="onResume" native="false" return="void" static="false" synchronized="false" visibility="public"> </method> <!--boolean receiveFile(int paramInt, Intent paramIntent);--> <method abstract="false" deprecated="not deprecated" final="false" name="receiveFile" native="false" return="void" static="false" synchronized="false" visibility="public"> <parameter name="paramInt" type="int"> </parameter> <parameter name="paramIntent" type="android.content.Intent"> </parameter> </method> <method abstract="false" deprecated="not deprecated" final="false" name="loadUrl" native="false" return="void" static="false" synchronized="false" visibility="public"> <parameter name="paramString" type="java.lang.String"> </parameter> </method>
這樣非常簡單根據反編譯出來的物件 型別進行調整和命名即可 也不用扣破頭的想生成的咋不對呢 等等問題. 介面也是類似的處理邏輯
如果編譯不通過 可以檢視輸出 裡面會有詳細的提示
把所有的繫結編譯通過後 記得 加入相關依賴庫 就是你最初查找出來的
有時候智慧提示會出現卡殼 那怎麼知道我要的類是否生成出來? 可以藉助IlSpy 看下 如果出來了 即使 demo裡面有波浪號也不管他 只管編譯即可
開始寫個demo跑跑看
開始遇到第一個深坑。
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
第一個崩潰的異常出現 。查詢任何資料都沒有Xamarin相關的介紹。你會覺得神經病啊 啥垃圾Xamarin。。。 其實不是 如果你做安卓原生開發就會知道 使用kotlin的庫的時候 java這邊需要引入一個stblib
我們Xamarin早就提供了 nuget 搜尋下
加入這個庫再執行 就不會報錯了
至此整個流程完畢
如果執行過程出現
Java.Lang.NoClassDefFoundError: Failed resolution of: Lorg/jetbrains/anko/db/ManagedSQLiteOpenHelper; NoClassDefFoundError 請檢查下依賴的第三方jar 是否已經打在你繫結庫裡面 記得 一定要先清理 再編譯 否則 會讓你覺得崩潰 明明添加了 結果還是 沒找到 記得清空 跑下吧 我 已經放在github上了https://github.com/jsonsugar/XamainAndroidBindLibary