久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁  >  技術(shù)干貨  > Unity使用Obb擴(kuò)展包的正確姿勢(shì)

Unity使用Obb擴(kuò)展包的正確姿勢(shì)

來源:千鋒教育
發(fā)布人:qyf
時(shí)間: 2022-08-18 17:35:00 1660815300

未命名圖片 (3)

  由于Google Play上不能上傳大于100M的包,所以需要將應(yīng)用進(jìn)行Obb分包,資源文件打包到Obb中,在Apk啟動(dòng)的時(shí)候再從Obb擴(kuò)展文件中加載資源。

  如何生成Obb擴(kuò)展資源文件

  Unity可以自動(dòng)為你進(jìn)行分包操作,只需要你在發(fā)布安卓版本的時(shí)候進(jìn)行簡(jiǎn)單的設(shè)置,當(dāng)然也可以自己根據(jù)需求通過以下命令進(jìn)行分包。

  // jobb 命令在sdk\tools目錄下jobb -pn-pv-d \資源 -o G:\輸出包名(如main.1.com.google.obb)

  obb擴(kuò)展文件的命名規(guī)則為:

  main文件:main...obb

  patch文件:patch...obb

  按照Unity分包的規(guī)則,主APK文件主要包括Java、Native代碼、游戲腳本、插件以及第一個(gè)場(chǎng)景包含的所有資源。Obb包主要是資源文件,在Unity打包Apk過程中,會(huì)把所有的資源文件(包括 streaming Assets)打包到Assets目錄下,而Obb分包后會(huì)將第一個(gè)場(chǎng)景以外的資源都打包到Obb目錄中,在Apk啟動(dòng)后,會(huì)根據(jù)相應(yīng)命名規(guī)則從Obb中加載資源文件。而在Unity里面為了安全性還封裝了一些校驗(yàn)規(guī)則,下面會(huì)提取出相關(guān)的校驗(yàn)規(guī)則供我們下載校驗(yàn)(這只針對(duì)通過Unity直接打包會(huì)生成相關(guān)的校驗(yàn)規(guī)則,如果你是導(dǎo)出工程然后再進(jìn)行分包、打包那么Unity這套規(guī)則并不直接適用于你,為了安全性你可以自己實(shí)現(xiàn)一套類似的規(guī)則)。

  如何使用Obb擴(kuò)展資源文件

  大多數(shù)情況下,當(dāng)用戶從Google Play上下載應(yīng)用時(shí),Google Play會(huì)自動(dòng)將APK文件和擴(kuò)展文件同時(shí)下載下來,至于具體是哪些cases下Google Play無法下載擴(kuò)展文件并沒有說明,此外即使Google Play正確的下載了擴(kuò)展文件,但是由于擴(kuò)展文件存放的目錄是可以被用戶和其他應(yīng)用訪問的。但是Google Play并不總是保證一定會(huì)下載擴(kuò)展文件,一般情況下我們需要將生成的apk以及obb下載下來的擴(kuò)展文件有可能會(huì)被用戶或其他應(yīng)用刪除。

  其次,我們的安裝包除了在Google Play平臺(tái),也會(huì)在其他渠道上架,所以為了保證用戶下載簡(jiǎn)潔可靠,我們需要在應(yīng)用中自行實(shí)現(xiàn)擴(kuò)展文件完整性檢查和下載的機(jī)制。

  如何手動(dòng)下載Obb資源擴(kuò)展文件

  1.如果你的Obb擴(kuò)展文件上傳到Google平臺(tái),那么你可以使用Android中提供的APK擴(kuò)展文件下載庫Downloader Library來簡(jiǎn)化擴(kuò)展文件檢查和下載的邏輯,具體可以參考以及Google Play APK擴(kuò)展文件機(jī)制及開發(fā)流程詳解,然而這種方式限制多多,需要支持google框架,不能應(yīng)用于其他渠道等等...

  2.將擴(kuò)展文件上傳到自己的服務(wù)器,原理上就可以適用于所有的渠道,需要的就是實(shí)現(xiàn)一個(gè)網(wǎng)絡(luò)下載器。

  手動(dòng)校驗(yàn)Obb是否已經(jīng)下載完成

  UnityPlayer是一個(gè)UI場(chǎng)景類,在UnityPlayerActivity會(huì)初始化該類,在進(jìn)入游戲前,這個(gè)類里面會(huì)讀取本地Obb文件生成校驗(yàn)碼并與打包Apk時(shí),配置在setting.xml中的校驗(yàn)表對(duì)比,如果校驗(yàn)失敗,則不會(huì)進(jìn)入游戲場(chǎng)景,配置表如下:

  Assets/bin/Data/Setting.xml

<?xml version="1.0" encoding="UTF-8"?><settings>  <integer name="splash_mode">0</integer>  <bool name="useObb">True</bool>  <bool name="9f6f9912e7e5c791037078042be85f73">True</bool></settings>

  splash_mode:應(yīng)該是定義啟動(dòng)模式

  useObb:是否使用Obb,如果沒有使用Unity進(jìn)行Obb分包,那么該選項(xiàng)始終是False。

  9f6f9912e7e5c791037078042be85f73:表示加密算法生成的校驗(yàn)碼。

  項(xiàng)目中需要做的是在進(jìn)入游戲后去進(jìn)行一次Obb校驗(yàn),防止用戶重復(fù)下載Obb,如果校驗(yàn)失敗就需要我們?cè)谟螒蛑凶詣?dòng)去下載Obb包,我們把Unity中校驗(yàn)Obb的步驟拎出來,一共三部。

  檢測(cè)Obb文件是否存在

  根據(jù)Obb文件生成校驗(yàn)碼

  讀取setting.xml文件,并與校驗(yàn)碼做對(duì)比

  下面的具體的一些代碼,主要規(guī)則來源于UnityPlayer。

  獲取Obb文件

  /**

  * 獲取應(yīng)用obb位置

  * @param paramContext

  * @return

  */

  private static String[] getObbPath(Context paramContext) { String str1 = paramContext.getPackageName();

  VectorlocalVector = new Vector(); try {

  int i1 = paramContext.getPackageManager().getPackageInfo(str1, 0).versionCode; if (Environment.getExternalStorageState().equals("mounted")) {

  File localFile1 = Environment.getExternalStorageDirectory();

  File localFile2 = new File(localFile1.toString()

  + "/Android/obb/" + str1); if (localFile2.exists()) { if (i1 > 0) { String str3 = localFile2 + File.separator + "main."

  + i1 + "." + str1 + ".obb"; if (new File(str3).isFile()) {

  localVector.add(str3);

  }

  } if (i1 > 0) { String str2 = localFile2 + File.separator + "patch."

  + i1 + "." + str1 + ".obb"; if (new File(str2).isFile()) {

  localVector.add(str2);

  }

  }

  }

  } String[] arrayOfString = new String[localVector.size()];

  localVector.toArray(arrayOfString); return arrayOfString;

  } catch (PackageManager.NameNotFoundException localNameNotFoundException) {

  } return new String[0];

  }

  加密生成校驗(yàn)碼算法:

  /**

  * 通過obb文件獲取加密MD5

  * @param paramString

  * @return

  */

  private static String getMd5(String paramString) { try {

  Log.d("WARX", "path = " + paramString);

  MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");

  FileInputStream localFileInputStream = new FileInputStream(

  paramString); long lenght = new File(paramString).length();

  localFileInputStream.skip(lenght - Math.min(lenght, 65558L)); byte[] arrayOfByte = new byte[1024]; for (int i2 = 0; i2 != -1; i2 = localFileInputStream

  .read(arrayOfByte)) {

  localMessageDigest.update(arrayOfByte, 0, i2);

  }

  BigInteger bi = new BigInteger(1, localMessageDigest.digest());

  Log.d("WARX", "md5 = " + bi.toString(16)); return bi.toString(16);

  } catch (FileNotFoundException localFileNotFoundException) {

  } catch (IOException localIOException) {

  } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {

  } return null;

  }

  這里主要是根據(jù)文件的長(zhǎng)度生成的一個(gè)md校驗(yàn)碼。

  解析XML算法:

  private static Bundle getXml(Context context) {

  Bundle bundle = new Bundle();

  XmlPullParser localXmlPullParser; // int i1;

  String str; try {

  File localFile = new File(context.getPackageCodePath(), "assets/bin/Data/settings.xml"); Object localObject1; if (localFile.exists())

  localObject1 = new FileInputStream(localFile); else

  localObject1 = context.getAssets()

  .open("bin/Data/settings.xml");

  XmlPullParserFactory localXmlPullParserFactory = XmlPullParserFactory

  .newInstance();

  localXmlPullParserFactory.setNamespaceAware(true);

  localXmlPullParser = localXmlPullParserFactory.newPullParser();

  localXmlPullParser.setInput((InputStream) localObject1,null);

  int type = localXmlPullParser.getEventType(); Object localObject2 = null;

  str = null; while (type!=1) { switch (type) { case 2: if (localXmlPullParser.getAttributeCount()==0) {

  type = localXmlPullParser.next(); continue;

  }

  str = localXmlPullParser.getName();

  localObject2 = localXmlPullParser.getAttributeName(0); if (!localXmlPullParser.getAttributeName(0).equals("name")){

  type = localXmlPullParser.next(); continue;

  }

  localObject2 = localXmlPullParser.getAttributeValue(0); if (str.equalsIgnoreCase("integer")) {

  bundle.putInt((String) localObject2,

  Integer.parseInt(localXmlPullParser.nextText()));

  } else if (str.equalsIgnoreCase("string")) {

  bundle.putString((String) localObject2,

  localXmlPullParser.nextText());

  } else if (str.equalsIgnoreCase("bool")) {

  bundle.putBoolean((String) localObject2, Boolean

  .parseBoolean(localXmlPullParser.nextText()));

  } else if (str.equalsIgnoreCase("float")) {

  bundle.putFloat((String) localObject2,

  Float.parseFloat(localXmlPullParser.nextText()));

  } break; default: break;

  }

  type = localXmlPullParser.next();

  }

  } catch (Exception localException) {

  localException.printStackTrace();

  } return bundle;

  }

  這里將xml中的數(shù)據(jù)讀取到一個(gè)Bundle中進(jìn)行保存,Bundle內(nèi)部實(shí)現(xiàn)是Map。最后我們可以將生成的校驗(yàn)碼與setting.xml中獲取的校驗(yàn)碼進(jìn)行對(duì)比,如果校驗(yàn)失敗就可以啟動(dòng)下載流程了,下載完成后重啟Activity,重新讀取Obb文件并加載資源。

  /**

  * 重啟Activity

  * @param context

  */

  public static void restartApplication(Activity context) {

  PackageManager packageManager = context.getPackageManager();

  Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());

  ComponentName componentName = intent.getComponent();

  Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);

  mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);

  context.startActivity(mainIntent);

  System.exit(0);

  }

  關(guān)于使用obb所涉及到的權(quán)限問題

  最近需要把應(yīng)用所用的權(quán)限最小化,那么獲取obb是否需要權(quán)限,這是一個(gè)非??拥臇|西,先看看官方的文檔。

  從文檔上可以看出來,是android 6.0需要權(quán)限,除了6.0都無需權(quán)限,但是使用我們手里的6.0設(shè)備去嘗試沒有權(quán)限都可以下載obb正常進(jìn)行游戲,但是使用google play下載之后部分6.0機(jī)型讀取bugly上報(bào)訪問obb路徑被拒絕了,使用測(cè)試機(jī)也發(fā)現(xiàn)是偶發(fā)現(xiàn)象,下載了多次游戲,第一次的時(shí)候出現(xiàn)了訪問路徑拒絕,這就非常的蛋疼了。加上權(quán)限是肯定不會(huì)出問題的,我們剔除權(quán)限前游戲從未上報(bào)過這個(gè)問題,目前我們是增加了用戶讀取內(nèi)存權(quán)限解決問題。

  更多關(guān)于unity培訓(xùn)的問題,歡迎咨詢千鋒教育在線名師。千鋒教育擁有多年IT培訓(xùn)服務(wù)經(jīng)驗(yàn),采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,擁有國內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),助力更多學(xué)員實(shí)現(xiàn)高薪夢(mèng)想。

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
軟件開發(fā)管理流程中會(huì)出現(xiàn)哪些問題?

一、需求不清需求不明確是導(dǎo)致項(xiàng)目失敗的主要原因之一。如果需求沒有清晰定義,開發(fā)人員可能會(huì)開發(fā)出不符合用戶期望的產(chǎn)品。二、通信不足溝通問...詳情>>

2023-10-14 13:43:21
軟件定制開發(fā)中的敏捷開發(fā)是什么?

軟件定制開發(fā)中的敏捷開發(fā)是什么軟件定制開發(fā)中的敏捷開發(fā),從宏觀上看,是一個(gè)高度關(guān)注人員交互,持續(xù)開發(fā)與交付,接受需求變更并適應(yīng)環(huán)境變化...詳情>>

2023-10-14 13:24:57
什么是PlatformIo?

PlatformIO是什么PlatformIO是一個(gè)全面的物聯(lián)網(wǎng)開發(fā)平臺(tái),它為眾多硬件平臺(tái)和開發(fā)環(huán)境提供了統(tǒng)一的工作流程,有效簡(jiǎn)化了開發(fā)過程,并能兼容各種...詳情>>

2023-10-14 12:55:06
云快照與自動(dòng)備份有什么區(qū)別?

1、定義和目標(biāo)不同云快照的主要目標(biāo)是提供一種快速恢復(fù)數(shù)據(jù)的方法,它只記錄在快照時(shí)間點(diǎn)后的數(shù)據(jù)變化,而不是所有的數(shù)據(jù)。自動(dòng)備份的主要目標(biāo)...詳情>>

2023-10-14 12:48:59
服務(wù)器為什么要用Linux?

服務(wù)器為什么要用Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,Linux在眾多選擇中脫穎而出。Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,有其獨(dú)特的優(yōu)勢(shì)和特點(diǎn)。包括其...詳情>>

2023-10-14 12:34:11
快速通道