ResourceManager(八)—— 在安卓机子上实现加载AssetBundle

本文介绍如何在Unity项目中实现安卓平台的热更新功能。主要内容包括生成assetbundle包、复制必要文件到PersistentAssets目录、解析AssetInfo.bytes文件并按需复制资源文件等步骤。
上一篇的demo只能在windows上运行,这一篇看看在安卓上怎么搞。
1.首先肯定还是要先点击工具栏Build/BuildAndroid生成assetbundle。
2.把Assets/assetbundles里面的东西全拖到Assets/StreamingAssets文件夹下面。
3.可以打包运行了。

接下来看看在安卓机上的运行流程:
1.从StreamingAssets文件夹下先复制AssetInfo.bytes,Resource.bytes,Version.bytes三个文件到PersistentAssets目录下。
2.读取AssetInfo.bytes中保存的路径信息,然后把对应的StreamingAssets下的资源复制PersistentAssets目录下。
3.点击button。跳转到TestScene。

就这样吧,手机截图不好上传,就不截图了。

这一篇相对于上一篇只有UpdateSceneScript.cs改变了的:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml;

public class UpdateSceneScript : MonoBehaviour 
{
    //这个路径是可以用的,测试过了
    string StreamingAssetPath;
    string PersistentPath;

    //存放所有资源的路径
    List<string> mAllAssetPath = new List<string> ();

    void Start () 
    {
        StreamingAssetPath = "jar:file://" + Application.dataPath + "!/assets/";
        PersistentPath = Application.persistentDataPath + "/";

        //靠AssetInfo.bytes文件是否存在来判断是否已经复制过了
        if (File.Exists(PersistentPath + "AssetInfo.bytes"))
        {
            Debug.Log ("files exist already, do not neead to copy files from StreamAssetPath to PersistentDataPath!!!");
        }
        //开始复制
        else
        {
            //1.复制AssetInfo.bytes
            StartCoroutine (CopyAssetInfoFile ());
            //1.复制Resource.bytes
            StartCoroutine (CopyResourceFile ());
            //1.复制Version.bytes
            StartCoroutine (CopyVersionFile ());
        }
    }

    //复制AssetInfo.bytes文件
    private IEnumerator CopyAssetInfoFile()
    {
        Debug.Log ("Copying AssetInfo.bytes File !!!");
        WWW www = new WWW (StreamingAssetPath + "AssetInfo.bytes");
        yield return www;

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log ("Copying AssetInfo.bytes should not error!!!");
            www.Dispose ();
        }
        else
        {
            //把AssetInfo.bytes写到persitentPath下面去
            File.WriteAllBytes (PersistentPath + "AssetInfo.bytes", www.bytes);
            www.Dispose ();

            //因为AssetInfo.bytes对于复制其他资源文件是必须的,所以必须先复制了才行
            //2.开始读取AssetInfo.bytes内的信息
            GetAssetPaths ();
        }
    }

    //复制Resource.bytes文件
    private IEnumerator CopyResourceFile()
    {
        Debug.Log ("Copying Resource.bytes file !!!");
        WWW www = new WWW (StreamingAssetPath + "Resource.bytes");
        yield return www;

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log ("Copying Resource.bytes should not error!!!");
            www.Dispose ();
        }
        else
        {
            //把AssetInfo.bytes写到persitentPath下面去
            File.WriteAllBytes (PersistentPath + "Resource.bytes", www.bytes);
            www.Dispose ();
        }
    }

    //复制Version.bytes文件
    private IEnumerator CopyVersionFile()
    {
        Debug.Log ("Copying Version.bytes file !!!");
        WWW www = new WWW (StreamingAssetPath + "Version.bytes");
        yield return www;

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log ("Copying Version.bytes should not error!!!");
            www.Dispose ();
        }
        else
        {
            //把AssetInfo.bytes写到persitentPath下面去
            File.WriteAllBytes (PersistentPath + "Version.bytes", www.bytes);
            www.Dispose ();
        }
    }

    //获取AssetInfo.bytes中路径信息
    private void GetAssetPaths()
    {
        if (File.Exists(PersistentPath + "AssetInfo.bytes"))
        {
            FileStream fs =  File.Open (PersistentPath + "AssetInfo.bytes", FileMode.Open, FileAccess.Read, FileShare.Read);
            StreamReader assetInfoSW = new StreamReader (fs, System.Text.Encoding.Default);
            XmlDocument doc = new XmlDocument ();
            doc.LoadXml (assetInfoSW.ReadToEnd ());
            XmlElement root = doc.DocumentElement;

            IEnumerator iter = root.GetEnumerator ();
            while (iter.MoveNext())
            {
                XmlElement child_root = iter.Current as XmlElement;
                string name = child_root.GetAttribute ("name");
                mAllAssetPath.Add (name);
            }
            fs.Close ();
            assetInfoSW.Close ();

            Debug.Log ("Get all assets path completed!!!");
        }

        Debug.Log ("Start Copy ! ! !");
        //3.开始复制
        StartCopy ();

        Debug.Log ("ALl files copied completed");

    }

    void OnGUI()
    {
        //6.全部加载完了就开始加载TestScene
        if (GUI.Button(new Rect(10, 10, 100, 100), "button"))
        {
            //完成初始化
            ResourcesManager.Instance.Init ();

            //加载场景
            ResourcesManager.Instance.loadLevel ("Scenes/TestScene", null);
        }
    }

    //开始资源文件的复制
    private void StartCopy()
    {
        //文件路径
        string file = mAllAssetPath [0];

        mAllAssetPath.RemoveAt (0);

        //4.www加载
        StartCoroutine (WwwDownload (file, delegate(WWW www)
        {
                //5.www加载好了就开始复制
                CopyToPersistent(file, www);

                //销毁
                www.Dispose();

                //递归copy
                StartCopy();
        }));

    }

    private delegate void HandleCopyCompleted(WWW www);

    //WWW加载StreamingAssets下的资源
    private IEnumerator WwwDownload(string filePath, HandleCopyCompleted handle)
    {
        //源路径
        string filePathSrc = StreamingAssetPath + filePath + ".bytes";

        WWW www = new WWW (filePathSrc);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log ("should not error!!!");
            www.Dispose ();
        }
        else
        {
            if (handle != null)
            {
                handle (www);
            }
            //www.Dispose ();
        }
    }

    //复制操作
    private void CopyToPersistent(string filePath, WWW www)
    {       
        //目标路径
        string filePathDest = PersistentPath + filePath + ".bytes";
        string filePathDestFolder = ResourceCommon.getPath (PersistentPath + filePath);

        if (!Directory.Exists(filePathDestFolder))
        {
            Directory.CreateDirectory (filePathDestFolder);
            Debug.Log ("Create Directory!!!");
            Debug.Log ("filePathDestFolder: + " + filePathDestFolder);
        }

        File.WriteAllBytes (filePathDest, www.bytes);
    }
}
<think>好的,用户想知道如何从Hadoop伪分布式模式迁移到完全分布式模式。我需要根据提供的引用资料来整理步骤。首先,引用[3]提到了分发Hadoop文件到各个节点并格式化namenode,这应该是关键步骤。 首先,用户需要准备多个节点,比如node01到node04,确保它们之间SSH免密登录,这样分发文件时不会遇到权限问题。然后,修改Hadoop的配置文件,比如core-site.xml、hdfs-site.xml、mapred-site.xml和yarn-site.xml,这些配置需要指向完全分布式的节点,而不是本地回环地址。引用[1]和[2]提到了配置文件的修改,特别是core-site.xml中的fs.defaultFS属性需要更改为namenode的主机名和端口。 接下来,分发Hadoop安装目录到所有节点,引用[3]中的例子使用了scp命令,这里需要确保路径正确,每个节点上的安装目录一致。然后,格式化HDFS,只在namenode节点执行一次格式化,避免多次格式化导致数据不一致。启动Hadoop集群时,应该分别在namenode和resourcemanager节点启动相应的服务。 用户可能遇到的问题包括网络配置、SSH设置以及配置文件错误,需要检查这些部分。另外,引用[3]提到格式化namenode,这是一个重要步骤,必须正确执行。最后,验证集群是否正常运行,可以通过Web界面或运行示例作业来测试。 需要确保用户理解每个步骤的作用,例如修改配置文件是为了让各个组件知道彼此的地址,分发文件是为了保持所有节点上的配置一致。同时,强调格式化只能执行一次,否则会丢失数据。可能用户在实际操作中会遇到权限问题,需要指导如何正确设置目录权限和SSH密钥。 总结步骤:准备节点、修改配置、分发文件、格式化HDFS、启动集群、验证测试。确保每个步骤都清晰,并指出常见错误点,帮助用户顺利完成迁移。</think>以下是Hadoop从伪分布式迁移到完全分布式模式的配置步骤,结合引用内容整理: ### 一、节点准备 1. 准备至少3台节点(如node01、node02、node03) 2. 确保节点间已配置: - 主机名映射(/etc/hosts) - SSH免密登录 - 相同的Java环境 - 统一时间同步 ### 二、关键配置文件修改 1. **core-site.xml**: ```xml <property> <name>fs.defaultFS</name> <!-- 改为namenode的主机名 --> <value>hdfs://node01:9000</value> </property> ``` 2. **hdfs-site.xml**: ```xml <property> <name>dfs.replication</name> <value>3</value> <!-- 设置副本数为节点数量 --> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>node02:50090</value> </property> ``` 3. **mapred-site.xml**: ```xml <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> ``` 4. **yarn-site.xml**: ```xml <property> <name>yarn.resourcemanager.hostname</name> <value>node02</value> </property> ``` ### 三、文件分发与初始化 1. 分发安装目录到所有节点(引用[3]方法): ```bash scp -r /usr/local/hadoop node02:/usr/local/ scp -r /usr/local/hadoop node03:/usr/local/ ``` 2. 格式化HDFS(仅在namenode执行): ```bash hdfs namenode -format ``` ### 四、集群启动 1. 在namenode(node01)启动HDFS: ```bash start-dfs.sh ``` 2. 在resourcemanager节点(node02)启动YARN: ```bash start-yarn.sh ``` ### 五、验证测试 1. 检查节点状态: ```bash hdfs dfsadmin -report yarn node -list ``` 2. 通过Web界面验证: - NameNode:http://node01:50070 - ResourceManager:http://node02:8088
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值