zoukankan      html  css  js  c++  java
  • 【InjectFix】InjectFix热修复的使用

     
    InjectFix可以看做XLua的升级版,能直接在unity工程上修改C#代码即可更新,符合苹果热更新条款
     

    一、原理:

    虚拟机负责新逻辑的解析执行;注入代码负责把调用重定向到虚拟机;
     

    二、Demo使用流程和方法:

    1.安装
    下载解压后,VSProj文件夹下的built_for_unity.bat文件,编辑修改UNITY_HOME为本机unity安装目录,保存之后运行
     
    IFixToolKit文件夹在和Asset文件夹同级目录,Assets文件夹下有IFix和Plugins文件夹
     
    打开之后可以看到:
    Inject:注入,对工程进行一系列操作,保存当前状态,Inject之后就不能生成补丁了
     Fix:生成一个热修复文件,文件就是用来热修复的,以.bytes结尾
     
    2.配置热更新
    热更新的实现依赖于提前做些静态代码插入,需要做配置类
    而且配置必须打[Configure]标签 必须放在Editor目录下,创个脚本在Editor下
    //两种方式
    //1、配置类必须打[Configure]标签
    //2、必须放Editor目录
    [Configure]
    public class HelloworldCfg
    {
        [IFix]
        private static IEnumerable<Type> hotfix
        {
            get
            {
                return new List<Type>()
                {
                    typeof(Helloworld),
                    typeof(IFix.Test.Calculator),
                    //AnotherClass在Pro Standard Assets下,会编译到Assembly-CSharp-firstpass.dll下,用来演示多dll的修复
                    typeof(AnotherClass),
                };
            }
        }
        
        [IFix]
        private static IEnumerable<Type> ToProcess
        {
            get
            {
                return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
                        where type.Namespace == "XLua" && !type.Name.Contains("<")
                        select type);
                //对XLua命名空间下进行插入
            }
        }
    }
    注:
    *配置类打上Configure标签
    *配置的属性打上IFix标签,而且必须是 __static__ 类型
     
    3.修改bug打补丁
    如:
    错误的代码:
    public int Add(int a, int b)
    {
      return a - b;
    }

    在方法上打上[Patch]标签并修改里面内容

    [Patch]
    public int Add(int a, int b)
    {
        return a + b;
    }

    保存之后执行InjectFix/Fix菜单,在项目文件夹中生成.bytes文件

    4.上传补丁
    实际项目可上传到服务器中加载,在此仍然在原项目中使用,将Assembly-CSharp.patch.bytes文件放在Resources文件夹中。
     

    更新:

    三、在新项目中使用InjectFix

    GitHub:https://github.com/caoweigang/InjectFixDemo

    1.安装InjectFix到新项目中:

     

    1)下载示例代码后,修改VSProj下的build_for_unity.bat文件,首行改为Unity的安装目录

    2)运行build_for_unity.bat文件。

    3)之后可以在UnityProj文件夹中看到IFixToolKit文件夹,将此文件夹复制到项目的Assets的同级目录

    4)示例项目中的IFix文件夹Plugins文件夹复制到项目的Assets文件夹下

    2.配置类预处理代码:

    和xLua类似,热补丁的实现依赖于提前做些静态代码插入,对热更的类进行预处理。
    两种方式:指定类、指定命名空间下的所有类。
    注意:配置文件必须添加[Configure]标签,放在Editor文件夹下
    [Configure]
    public class MyConfig
    {
        [IFix]
        private static IEnumerable<Type> ToProcess
        {
            get
            {
                return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
                        where type.Namespace == "XXXXX" && !type.Name.Contains("<")
                        select type);
            }
        }
    }
        [IFix]
        private static IEnumerable<Type> hotfix
        {
            get
            {
                return new List<Type>()
                {
                    typeof(HotFixMgr),
                    typeof(MyGame.TestScr),
                    //AnotherClass在Pro Standard Assets下,会编译到Assembly-CSharp-firstpass.dll下,用来演示多dll的修复
                    //typeof(AnotherClass),
                };
            }
        }
    过滤:
      [IFix.Filter]
        private static bool Filter(System.Reflection.MethodInfo methodInfo)
        {
            return methodInfo.DeclaringType.FullName == "IFix.Test.Calculator"
                && (methodInfo.Name == "Div" || methodInfo.Name == "Mult");
        }

    3.加载补丁文件Assembly-CSharp.patch代码:

    //在项目启动时候加载补丁文件
    private async void DownloadScriptFixPatch()
    {
         //#if !UNITY_EDITOR
         var patch = Resources.Load<TextAsset>("Assembly-CSharp.patch");
         if (patch != null)
         {
            //UnityEngine.Debug.Log("loading Assembly-CSharp.patch ...");
            //var sw = Stopwatch.StartNew();
            PatchManager.Load(new MemoryStream(patch.bytes));
            //UnityEngine.Debug.Log("patch Assembly-CSharp.patch, using " + sw.ElapsedMilliseconds + " ms");
        }
        //#endif
        var patch = await AssetCacheService.Instance.LoadByteAssetFromServer("FIX/Assembly-CSharp.patch.bytes");
        if (patch != null)
        {
             PatchManager.Load(new MemoryStream(patch));
        }
    }

    4.生成补丁并使用的过程(仅修改方法,不添加属性方法和类)

     1)在需要修改的方法打上[Patch]标签

    [Patch]
    private void SetView()
    {
         title.text = GetString();
         content.text = contentStr;
         bg.color = color;
    }

    2)修改过代码之后使用InjectFix/Fix,生成Assembly-CSharp.patch补丁文件,即包含了当前修改内容。

    3)上传补丁文件到服务器
    4)在Unity中模拟时放在Resource文件中,并且需要InjectFit/Inject

    5.添加属性、新增方法、新增类使用[Interpret]

    private string name;//这个name字段是原生的
    
    public string Name
    {
        [IFix.Interpret]
        set
        {
            name = value;    
        }
        [IFix.Interpret]
        get
        {
            return name;
        }
    }
            
            
    [Interpret]
    private string GetString()
    {
         return "123";
    }
    
    [IFix.Interpret]
    public class NewClass
    {
        ...类中增加的方法也应打标签
    }
     

  • 相关阅读:
    2019牛客暑期多校训练营(第三场)- LRU management
    2019牛客暑期多校训练营(第三场)- F Planting Trees
    HDU1392 Surround the Trees
    2019 Multi-University Training Contest 2
    3101 阶乘分解 (数学)
    Prime Distance POJ
    反素数ant HYSBZ
    B. Nirvana Codeforces Round #549 (Div. 2) (递归dfs)
    C. Queen Codeforces Round #549 (Div. 2) (搜索)
    Cow Relays POJ
  • 原文地址:https://www.cnblogs.com/weigangblog/p/14080959.html
Copyright © 2011-2022 走看看