AssemblyHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Reflection;
  4. using System;
  5. using System.IO;
  6. /// <summary>
  7. /// 符号集管理类
  8. /// </summary>
  9. public class AssemblyHelper : MonoSingleton<AssemblyHelper>
  10. {
  11. /// <summary>
  12. /// 符号集
  13. /// </summary>
  14. private Assembly mAssembly = null;
  15. /// <summary>
  16. /// 对象苏醒
  17. /// </summary>
  18. protected override void OnAwake()
  19. {
  20. base.OnAwake();
  21. //DontDestroyOnLoad(this);
  22. }
  23. /// <summary>
  24. /// 对象销毁
  25. /// </summary>
  26. protected override void DoOnDestroy()
  27. {
  28. base.DoOnDestroy();
  29. mAssembly = null;
  30. }
  31. /// <summary>
  32. /// 初始化符号集
  33. /// </summary>
  34. /// <param name="file">assetbundle文件完整路径</param>
  35. /// <param name="asset">资源名称</param>
  36. public void InitializeAssembly(string file, string asset, Action ac)
  37. {
  38. switch (Application.platform)
  39. {
  40. case RuntimePlatform.Android:
  41. {
  42. Debug.Log("安卓下初始化符号集" + file);
  43. // 后期考虑dll加密
  44. byte[] ctx = ReadFileBytes(file);
  45. if (null != ctx)
  46. {
  47. AssetBundle bundle = AssetBundle.LoadFromMemory(ctx);
  48. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  49. mAssembly = Assembly.Load(text.bytes);
  50. if (null == mAssembly)
  51. {
  52. Debug.LogError("安卓下初始化符号集" + name + "失败");
  53. }
  54. bundle.Unload(false);
  55. if (ac != null)
  56. {
  57. ac();
  58. }
  59. }
  60. else
  61. {
  62. LoadStreamingAssetsCode((data) =>
  63. {
  64. if (data != null)
  65. {
  66. AssetBundle bundle = AssetBundle.LoadFromMemory(data);
  67. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  68. mAssembly = Assembly.Load(text.bytes);
  69. if (null == mAssembly)
  70. {
  71. Debug.LogError("安卓下初始化符号集" + name + "失败");
  72. }
  73. bundle.Unload(false);
  74. if (ac != null)
  75. {
  76. ac();
  77. }
  78. }
  79. else
  80. {
  81. Debug.LogError("无法查找到文件:" + file);
  82. }
  83. });
  84. }
  85. }
  86. break;
  87. case RuntimePlatform.WindowsEditor:
  88. {
  89. Debug.Log("编辑器下初始化符号集" + file);
  90. // 后期考虑dll加密
  91. byte[] ctx = ReadFileBytes(file);
  92. if (null != ctx)
  93. {
  94. AssetBundle bundle = AssetBundle.LoadFromMemory(ctx);
  95. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  96. mAssembly = Assembly.Load(text.bytes);
  97. if (null == mAssembly)
  98. {
  99. Debug.LogError("编辑器下初始化符号集" + name + "失败");
  100. }
  101. bundle.Unload(false);
  102. if (ac != null)
  103. {
  104. ac();
  105. }
  106. }
  107. else
  108. {
  109. LoadStreamingAssetsCode((data) =>
  110. {
  111. if (data != null)
  112. {
  113. AssetBundle bundle = AssetBundle.LoadFromMemory(data);
  114. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  115. mAssembly = Assembly.Load(text.bytes);
  116. if (null == mAssembly)
  117. {
  118. Debug.LogError("编辑器下初始化符号集" + name + "失败");
  119. }
  120. bundle.Unload(false);
  121. if (ac != null)
  122. {
  123. ac();
  124. }
  125. }
  126. else
  127. {
  128. Debug.LogError("无法查找到文件:" + file);
  129. }
  130. });
  131. }
  132. }
  133. break;
  134. case RuntimePlatform.IPhonePlayer:
  135. case RuntimePlatform.OSXEditor:
  136. {
  137. Debug.Log("IOS下初始化符号集" + file);
  138. // 后期考虑dll加密
  139. byte[] ctx = ReadFileBytes(file);
  140. if (null != ctx)
  141. {
  142. AssetBundle bundle = AssetBundle.LoadFromMemory(ctx);
  143. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  144. mAssembly = Assembly.Load(text.bytes);
  145. if (null == mAssembly)
  146. {
  147. Debug.LogError("IOS下初始化符号集" + name + "失败");
  148. }
  149. bundle.Unload(false);
  150. if (ac != null)
  151. {
  152. ac();
  153. }
  154. }
  155. else
  156. {
  157. LoadStreamingAssetsCode((data) =>
  158. {
  159. if (data != null)
  160. {
  161. AssetBundle bundle = AssetBundle.LoadFromMemory(data);
  162. TextAsset text = bundle.LoadAsset(asset, typeof(TextAsset)) as TextAsset;
  163. mAssembly = Assembly.Load(text.bytes);
  164. if (null == mAssembly)
  165. {
  166. Debug.LogError("IOS下初始化符号集" + name + "失败");
  167. }
  168. bundle.Unload(false);
  169. if (ac != null)
  170. {
  171. ac();
  172. }
  173. }
  174. else
  175. {
  176. Debug.LogError("无法查找到文件:" + file);
  177. }
  178. });
  179. }
  180. }
  181. break;
  182. }
  183. }
  184. /// <summary>
  185. /// 绑定脚本到指定对象上
  186. /// </summary>
  187. /// <param name="name">反射名称</param>
  188. /// <param name="parent">附加到的目标对象</param>
  189. /// <returns>绑定成功后的组件对象</returns>
  190. public Component BindScript(string name, GameObject parent)
  191. {
  192. switch (Application.platform)
  193. {
  194. case RuntimePlatform.Android:
  195. {
  196. if (null == mAssembly)
  197. {
  198. //Debug.LogError("!!!!安卓下绑定脚本失败,符号集为空.转向本地绑定!!!_" + name);
  199. // 转向本地化处理
  200. Type val = Type.GetType(name);
  201. return parent.AddComponent(val);
  202. }
  203. System.Type script = mAssembly.GetType(name);
  204. if (script == null)
  205. {
  206. Type val = Type.GetType(name);
  207. return parent.AddComponent(val);
  208. }
  209. return parent.AddComponent(script);
  210. }
  211. case RuntimePlatform.WindowsEditor:
  212. {
  213. if (null == mAssembly)
  214. {
  215. // Debug.LogError("!!!!编辑器下绑定脚本失败,符号集为空.转向本地绑定!!!_" + name);
  216. // 转向本地化处理
  217. Type val = Type.GetType(name);
  218. return parent.AddComponent(val);
  219. }
  220. System.Type script = mAssembly.GetType(name);
  221. if (script == null)
  222. {
  223. Type val = Type.GetType(name);
  224. return parent.AddComponent(val);
  225. }
  226. // Debug.Log(script + " n " +name);
  227. return parent.AddComponent(script);
  228. }
  229. case RuntimePlatform.IPhonePlayer:
  230. case RuntimePlatform.OSXEditor:
  231. {
  232. //if (null == mAssembly)
  233. //{
  234. // Type val = Type.GetType(name);
  235. // return parent.AddComponent(val);
  236. //}
  237. //System.Type script = mAssembly.GetType(name);
  238. //return parent.AddComponent(script);
  239. if (null == mAssembly)
  240. {
  241. // Debug.LogError("!!!!编辑器下绑定脚本失败,符号集为空.转向本地绑定!!!_" + name);
  242. // 转向本地化处理
  243. Type val = Type.GetType(name);
  244. return parent.AddComponent(val);
  245. }
  246. System.Type script = mAssembly.GetType(name);
  247. if (script == null)
  248. {
  249. Type val = Type.GetType(name);
  250. return parent.AddComponent(val);
  251. }
  252. // Debug.Log(script + " n " +name);
  253. return parent.AddComponent(script);
  254. }
  255. }
  256. // 其他环境下处理
  257. Type tp = Type.GetType(name);
  258. return parent.AddComponent(tp);
  259. }
  260. /// <summary>
  261. /// 读取指定文件字节流
  262. /// </summary>
  263. /// <param name="file">文件路径</param>
  264. /// <returns>失败null,否则字节流</returns>
  265. private byte[] ReadFileBytes(string file)
  266. {
  267. if (false == File.Exists(file))
  268. {
  269. return null;
  270. }
  271. FileStream fs = new FileStream(file, FileMode.Open);
  272. long size = fs.Length;
  273. byte[] ctx = new byte[size];
  274. fs.Read(ctx, 0, ctx.Length);
  275. fs.Close();
  276. return ctx;
  277. }
  278. /// <summary>
  279. /// 加载StreamingAssets下的代码
  280. /// </summary>
  281. /// <param name="ac"></param>
  282. public void LoadStreamingAssetsCode(Action<byte[]> ac)
  283. {
  284. StartCoroutine(IELoadStreamingAssetsCode(ac));
  285. }
  286. /// <summary>
  287. /// 协同加载StreamingAssets下的code
  288. /// </summary>
  289. /// <param name="ac"> Lambda返回值</param>
  290. /// <returns></returns>
  291. private IEnumerator IELoadStreamingAssetsCode(Action<byte[]> ac)
  292. {
  293. Debug.Log("开始加载StreamingAssets下的代码");
  294. WWW www = new WWW(GetPath());
  295. yield return www;
  296. if (www.error == null)
  297. {
  298. if (ac != null)
  299. {
  300. ac(www.bytes);
  301. Debug.Log("StreamingAssets下的代码加载完成");
  302. }
  303. www.assetBundle.Unload(true);
  304. www.Dispose();
  305. }
  306. else
  307. {
  308. if (ac != null)
  309. {
  310. ac(null);
  311. }
  312. Debug.LogWarning("加载错误:" + www.error);
  313. }
  314. }
  315. /// <summary>
  316. /// 获取加载资源路径(用于 LoadFromFile 的同步和异步加载)
  317. /// </summary>
  318. /// <param name="strName">资源名称</param>
  319. /// <returns>返回实际路径</returns>
  320. public static string GetPath(string strName = "Core.unity3d")
  321. {
  322. string strPath = string.Empty;
  323. if (RuntimePlatform.Android == Application.platform)
  324. {
  325. strPath = Application.streamingAssetsPath + "/Res/" + strName;
  326. }
  327. else
  328. {
  329. strPath = "file://" + Application.streamingAssetsPath + "/Res/" + strName;
  330. }
  331. return strPath;
  332. }
  333. }