
在讨论WhatsApp卸载期间如何妥善管理消息以避免数据丢失之前,我们首先需要明确几个关键点。WhatsApp是一款全球范围内广泛使用的即时通讯应用,它允许用户通过互联网发送文本、语音、视频和图片等多媒体消息。当用户决定卸载WhatsApp时,如果不采取适当的措施,可能会导致重要消息的丢失。因此,在卸载WhatsApp之前,确保妥善管理消息显得尤为重要。
备份消息是至关重要的步骤之一。用户可以通过以下几种方式来备份WhatsApp消息:
-
导出聊天记录:WhatsApp提供了一个导出功能,允许用户将特定聊天记录导出为HTML文件或文本文件。具体操作方法如下:打开WhatsApp,点击右上角的菜单按钮,选择“设置” > “账户” > “聊天备份与恢复”。然后选择要导出的聊天记录,点击“导出聊天记录”。这样,您就可以将聊天记录保存到本地设备上,如电脑或移动设备的存储卡中。
-
使用云服务:许多用户选择将WhatsApp消息同步到云端服务(如Google Drive、Dropbox等),以便在不同设备之间访问和备份这些消息。这种方法的优点在于即使更换手机或电脑,仍然可以轻松访问备份的消息。不过需要注意的是,某些云服务可能需要额外付费才能享受无限存储空间。
-
第三方应用程序:还有一些专门用于备份WhatsApp消息的第三方应用程序,它们通常提供更多的功能,例如自动备份、加密保护等。不过,在选择此类工具时,请务必确保其安全性,并仔细阅读隐私政策和条款。

除了备份之外,清理不必要的消息也是防止数据丢失的一个有效方法。对于不再需要的消息,尤其是那些占用大量存储空间的多媒体文件(如大尺寸的照片或视频),可以考虑将其删除或转移到其他存储位置。这样做不仅可以释放宝贵的存储空间,还能减少因存储不足而导致的消息丢失风险。
在卸载WhatsApp之前,还需要注意检查是否有任何未完成的对话或通知。如果存在这样的情况,最好先处理好这些事务,以免在卸载后出现沟通上的不便。如果有任何重要信息尚未发送给联系人,也应尽快完成发送过程。
对于那些希望保留WhatsApp账号并重新安装应用的用户来说,他们可以在卸载后再次下载WhatsApp应用,并按照提示输入手机号码来恢复之前的聊天记录。需要注意的是,恢复过程中可能会遇到一些问题,例如某些消息可能无法完全恢复或者某些联系人可能不再在线等。因此,在此之前最好做好充分准备,并了解可能出现的问题及其解决方案。
在卸载WhatsApp之前,确保妥善管理消息是非常重要的。通过备份、清理和处理未完成事务等方式,可以最大限度地减少数据丢失的风险。同时,对于那些希望保留账号并重新安装应用的用户来说,遵循正确的恢复流程也将有助于顺利恢复之前的聊天记录。
本文目录导航:
- 如何做Unity3d的代码混淆
- 天生耳背能从事噪音作业么?
如何做Unity3d的代码混淆
Unity代码混淆方案内容提要:Unity引擎下的代码保护,由于Unity引擎的一些特殊性,实行起来较为复杂,在国内外业界并没有现成的方案。 笔者通过在《QQ乐团》项目上的实际尝试,得出了一种具体可行,能够有效保护代码逻辑的方案。 特此分享给关注Unity引擎的项目,希望能提供一些的参考。 背景Unity引擎上的程序执行在Mono运行时上,使用Mono编译出的程序集格式与标准一致。 C#是Unity引擎下主要的开发语言,它具备不少高级语言特性,如反射、元数据、内置序列化等。 但C#同时也是很容易被反编译的语言,如果不采用任何保护措施,使用常用的工具( Reflector)便能很容易得到可二次编译的代码。 对项目运营带来了比较大的风险。 平台下通常的保护手段是混淆编译出的程序集。 VisualStudio自带了一个混淆工具Dotfuscator可以对程序集进行混淆。 功能包括名称修改,流程混淆,字符串加密等。 经过Dotfuscator混淆后的程序集,能够避免被常用反编译工具破解。 变量的表意性被破坏,同时函数的内部流程也被混淆(如下[B1] )。 能有效起到保护源代码的效果。 publicclass181: 218{// Fieldspublicuint0;publicushort1;publicstaticreadonlyuint2;publicstaticreadonlyuint3;// Methodsstatic181();public181();public95.02();public95.02(ref515A_0, uintA_1);public95.02(79A_0, refuintA_1);public95.02(ref79A_0, uintA_1);public95.02(byte[] A_0, intA_1, refuintA_2);public95.02(ref481A_0, intA_1, charA_2);public95.02(refstringA_0, intA_1, charA_2);public95.02(refbyte[] A_0, intA_1, refintA_2, uintA_3);public95.03(ref79A_0, uintA_1);public95.03(refbyte[] A_0, intA_1, refintA_2, uintA_3);public95.04(refbyte[] A_0, intA_1, refintA_2, uintA_3);}public95.00(refsbyteA_0, intA_1){// This item is obfuscated and can not be Label_0006;if(1!= 0){}95.0local= 95.0.0;bytenum= 0;local = this.0(refnum,A_1);A_0 = (sbyte) num;returnlocal;Unity引擎下,Mono编译出的程序集,由于采用与相同的格式标准。 能够直接被Dotfuscator混淆。 但Unity引擎有一些特殊的地方,使混淆工作与一般的程序存在差异。 第三节将主要讨论这些特殊点。 Unity引擎下代码混淆的特殊性代码被资源引用[B2] 。 Unity的可视化编辑特性在设计上的关键之处在于使代码能够以组件的形式依附到资源实例上。 相比传统游戏,Unity的两类资源(scene和prefab)不仅包括数据,还包括附加在资源上的类对象。 也就是说,这两类资源的存储格式中存在唯一标识某代码类型的数据。 混淆流程必须不破环这种对应关系才能使资源上的代码逻辑正确被执行。 (Unity这样设计的意义并不是本文讨论的重点,而另一篇分享个人对Unity可视化编辑的理解的文章中将会详细说明。 )发布到Web的Unity项目,在生成播放器可执行包(*)的接口中,将编译程序集和打包这两个步骤捆绑在的一起。 我们没办法像普通程序那样,对编译出的程序集进行混淆后再打到播放器可执行包中。 UnityEngine按函数名进行调用。 MonoBehaviour是Unity引擎的一个重要的组件基类。 其上的很多方法,Unity是通过方法名称进行访问的,如Awake、Start、Update等等。 这些方法如果在混淆中被改名,将使方法调用失败。 这个问题相对比较好处理,Dotfuscator的重命名功能提供了排除配置。 我们只要得到继承于MonoBehaviour的所有类型,就能生成相应的排除配置,告知Dotfuscator不要对这些方法进行重命名。 生成的配置节选如下[B3] :xmlserialization思路 何时混淆?由于Web项目编译和打包的过程是捆绑在一起的,官方没有提供独立的接口。 (之前有跟官方反馈,但目前官方并没有提供具体计划。 )想自己来分析官方的打包格式是行不通并且不太科学的。 仅剩的办法就是自己将代码编译成DLL,混淆之后再添加到Unity项目中。 顺着这条思路,笔者在《QQ乐团》项目上作了尝试。 将项目中所有执行相关的代码(不包括编辑器扩展的代码)移出,指定相关的Unity依赖库,编译成DLL。 再将此DLL复制到原项目中。 这时意料之中的事情发生了——项目中所有资源上的代码引用全部丢失。 为了找到资源对代码的映射形式,笔者调整Unity编辑器的设定,将资源的序列化格式改为文本格式,并进行对比分析。 发现资源中是通过一个GUID来对应具体代码的[B4] 。 (如下) m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: } m_GameObject: {fileID: } m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID, guid: 8ae38faa3fc9fa5a9872bcc4b0f, type: 1} m_Name: mInt: 1 mFloat: .5 中的类型虽然还没有进行过混淆,但GUID已经发生了变化。 将新的GUID替换到资源文件中,引用关系果然恢复了。 Unity引擎下的特殊问题都是可以解决的。 于是顺着这思路,开发了若干工具,得到了前后GUID的对应关系,并扫描所有资源以进行GUID的替换。 另一方面,在混淆之后,类型的变量名发生了改变,资源中变量名赋有具体的值,也需要替换资源中的变量名对应到混淆后的变量名。 这一切花费了不少的精力,终于是把工具都做成了。 然而人算不如天算,最终导致此方案走进死角的是一个之前很难意料到的问题:Unity引擎在处理DLL中的模版类型时存在缺陷——DLL中的模版类型没有GUID,不能被资源所引用。 这个问题在Unity官方网站上有少量反馈,而官方承认了这个bug,且没有给出解决方案。 而《QQ乐团》的项目在UI操作上比较广泛地使用了模版类型,去除模版的使用谈何容易。 就这样,这么一个不经意的问题为这个尝试的方向画上了句号。 “系着枷锁跳舞”,这句话是形容的是在各种条件约束下尽可能的追求解决方案的一种状态。 总结之前的失败,最终还是找到了实际可行的改进方案,并成功应用到《QQ乐团》的Web版本和微客户端版本上。 最终的思路是将项目进行分层。 独立出一个不被资源引用的,包含最敏感的协议解析和各个系统模块的“逻辑层”,将逻辑层的代码独立编译成一个DLL,进行混淆再包含到项目中。 逻辑层之外的代码主要包括被资源引用到的,或是系统模块部分接口定义这样的不太敏感的内容,姑且称为“行为层”。 为了让逻辑层可以独立编译,我们要求逻辑层可对行为层进行引用,而行为层则只能通过留在行为层的逻辑层接口访问逻辑层。 这样我们就保护了我们最重要的代码,同时绕过了资源引用代码的问题。 这个方案对项目架构提出了一定的要求。 一是要求敏感代码和资源保持独立,需要一个框架来加载各个模块,而不是直接将模块代码直接附在场景物体的资源中。 二是要求层次清晰,不允许反向依赖。 有利于《QQ乐团》项目的消息是,《QQ乐团》从最早期就实现了一个较清晰的架构管理方法。 因此花费了一定的时间进行分层,和实现接口访问机制后,就成功执行了这个方案。 实际混淆步骤。 《QQ乐团》是使用VisualBuild来执行版本构建和发布流程的。 以下介绍版本构建中混淆相关的流程: 从Unity项目的Assets目录中拷贝出逻辑层的代码目录(CodeGameLogic)。 和编辑器扩展代码(避免混淆后编辑器扩展代码对逻辑层的依赖丢失导致编译出错)。 调用命令行编译剩余的行为层部分: 这个函数实际执行了: (new string[] {Assets/ }, WebPlayerObfuscated, , ); Editor程序集(也就是编辑器扩展程序集)时编译失败,中断编译过程,避免在BuildPlayer过程结束时构建生成的DLL被清理掉。 BuildPlayer之前故意在Editor目录下弄一个错误的代码文件即可。 将生成的行为层DLL拷贝到逻辑层构建目录。 行为层DLL的路径是在项目的Library/ScriptAssemblies下,有和两个文件。 另外也拷贝逻辑层依赖的其它DLL到构建目录,包括,以及项目Plugins目录下的依赖库。 调用Mono的编译器mcs编译逻辑层DLL——。 编译命令如下: 生成DotObfuscator的配置文件””。 这里是用自己编写的工具,扫描中的类型,得到不能被混淆的类型名和方法名,加入到配置文件的排出列表中。 如“三。 3”小节所示。 调用DotObfuscator对执行混淆,得到混淆后的: 将混淆后的拷贝到项目中,然后构建项目。 这里要注意的是,如果是构建Web项目,需要将dll拷贝到Plugins目录。 如果是Standalone(即客户端)项目,直接拷贝到Assets目录下即可。 另外,这次构建是不可以有编译错误的,所以第1部需要移除Editor目录下的编辑器扩展的代码。 接下来将构建好的项目与资源合并,就可以得到完整的混淆版本。 总结: Unity项目的代码反编译较为容易。 需要在重视代码混淆工作。 Unity项目的代码混淆方案实施起来限制较多。 本文介绍的方案是笔者知晓的目前唯一可用的混淆方案。 对项目的架构分层有强制性的要求。 最好是在项目初期就考虑如何对项目进行分层,将需要保护的内容放置在被混淆的层中。
天生耳背能从事噪音作业么?
不建议您从事噪声作业,耳朵长期在噪声污染的环境下会引起不舒适感,如耳鸣,甚至听力继续下降。