今天将这半个月在项目中采用的unity热更新技术及在使用过程中遇到的问题逐一总结一下,这篇文章主要来总结下www下载。
在项目中通过网络查找别人的文章,主要发现用于unity在线热更新的下载技术有两种,一种是本篇将要说明的www下载,还有一种是下篇将要说明的httpWebRequest下载,开始时由于介绍unity热更新www下载的文章比较多,且实现简单,采用了www下载,但是在实际项目中,由于www下载没有断点续传,所以在网络不稳定的情况下用户体验极差就改为了httpWebRequest下载,不过www下载下载一些比较小的文件还是没有什么问题的。
对了,在我的这个项目中untiy热更新没有实现代码的热更新,只实现资源AssetBundle的热更新,采用大小版本交叉的方式,由于不方便贴出来实际项目的代码,所以下面及以后贴出来的代码均为demo中已经验证过的部分代码过程。
代码如下:
using UnityEngine;
using System.Collections;
using System;
using System.IO;
public class WwwDown : MonoBehaviour
{
private string downURL = "http://153.37.232.46/sqdd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk?mkey=56417d90de3bd6cf&f=8f5d&p=.apk";
string targetPath = "";
string filename = "ALL-3DB";
private WWW wwwDown=null;
private string testString = "ceshi:";
// Use this for initialization
void Update()
{
//if (this.wwwDown != null && this.progressBar != null && !this.wwwDown.isDone)
//{
更新进度
// this.progressBar.value = this.wwwDown.progress;
//}
//测试
if (this.wwwDown != null && !this.wwwDown.isDone)
{
Debug.Log("Progress:" + this.wwwDown.progress);
}
}
void Start()
{
targetPath = Application.persistentDataPath;
Debug.Log (targetPath);
}
void OnGUI()
{
GUI.Label(new Rect(0, 60, Screen.width, Screen.height), testString);
if (GUI.Button(new Rect(0,0,80,30),"DownLoad"))
{
StartDownLoad();
}
if (GUI.Button(new Rect(100, 0, 80, 30), "IsExisted"))
{
IsExisted(filename);
}
if (GUI.Button(new Rect(200, 0, 80, 30), "DeleteFile"))
{
DeleteFile(filename);
}
if (GUI.Button(new Rect(300, 0, 80, 30), "StopDown"))
{
StopDown();
}
}
private void DisposeWWW()
{
//wwwDown.assetBundle.Unload(true);
//wwwDown.Dispose();
wwwDown = null;
//Resources.UnloadUnusedAssets();
}
//开始下载
public void StartDownLoad(){
Debug.Log("Start Down Load");
StartCoroutine(StartUnZip());
}
//判断是否存在
public void IsExisted(string name)
{
if (File.Exists(targetPath + "/" + filename+".assetbundle"))
{
//File.Delete(filePath);
Debug.Log("this is existed!");
}
}
//删除
public void DeleteFile(string name)
{
if (File.Exists(targetPath + "/" + filename + ".assetbundle"))
{
File.Delete(targetPath + "/" + filename + ".assetbundle");
}
}
//停止下载
public void StopDown()
{
Debug.Log("Stop Down Load");
StopCoroutine(StartUnZip());
DisposeWWW();
}
//下载部分
IEnumerator StartUnZip()
{
//加载本地文件也可,代码如下
wwwDown = new WWW(downURL);
Debug.Log("uri is:" + downURL);
yield return wwwDown;
if (wwwDown.error != null)
{
Debug.Log("loading is faile");
}
if (wwwDown.isDone)
{
Debug.Log("www is success");
}
//如果路径不存在 则创建
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
//把当前的压缩包写入到指定的路径下
File.WriteAllBytes(targetPath + "/" + filename + ".assetbundle", wwwDown.bytes);
DisposeWWW();
}
}
上面代码的地址部分为随便采用网上的连接地址(这个地址是httpwebrequest上的地址),在使用的时候改成自己的地址即可。demo如上共有4个功能,下载,停止,判断文件是否存在,以及删除文件。
在这里着重总结的为以下这个部分:
private void DisposeWWW()
{
//wwwDown.assetBundle.Unload(true);
//wwwDown.Dispose();
wwwDown = null;
//Resources.UnloadUnusedAssets();
}
{
//wwwDown.assetBundle.Unload(true);
//wwwDown.Dispose();
wwwDown = null;
//Resources.UnloadUnusedAssets();
}
由于原来做oc,深知资源管理的重要性,并且查找网上有些人的文章,他们也提到要将www下载的这部分内存进行处理,所以,开始的时候在下载完成与下载出错调用
wwwDown.Dispose();甚至调用
Resources.UnloadUnusedAssets();、
wwwDown.assetBundle.Unload(true);甚至
GC.Collect();但是不管进行如何处理总是会出现在多次开始停止下载,或是在大文件下载完成跳转场景时免不了出现崩溃的问题,后来多方查证了很多资料,并且发现官方都没有对www下载进行特殊的处理,才知道自己一开始就走上了一条错误的“不归路”。在这里着重说明以示警戒。
还有在做assetbundle的动态热更新时,资源路径采用Application.persistentDataPath,这主要是由于在安卓下其他的路径
Application.dataPath 、
Application.streamingAssetsPath基本都是只读路径,这个路径是读写路径(切记、切记、切记)。
本人文章纯属个人总结,且某些demo在项目采用前可能来自互联网,最终实验验证后实际项目中采用,若发现来自贵方,谅解;若发现,纰漏错误妄指正。