Tutorial: deep understanding of Flash sandbox-application domains

Source: Internet
Author: User
Tags get definition subdomain
Document directory
  • Note:
Transferred from: http://kevincao.com/2010/11/application-domains/application domain
  • Application domains application domain
  • Application domain placement application domain location
  • Application domain inheritance application domain inheritance
  • Child Domains: Definition versioning subdomain: defined version management
  • Separate domains: preventing conflicts domain separation: avoid conflict
  • Same domain: runtime shared libraries same domain: runtime shared library
  • Getting definitions dynamically dynamic get Definition
  • Same-definition collisions conflict with the same definition
  • Conclusion Summary
Application domains application domain

Like the Security global, SwF in different security sandboxes has its own class definition. This subdomain is defined under the security domain and the management class definition (the definitions of functions, interfaces, and namespaces are similar ).Application domain. The application domain only exists in the security domain and can only belong to a unique security domain. However, the security domain can contain multiple application domains.


Application domains in the security domain

Although the security domain sandbox is used to protect data security, the application sandbox domain is used to divide definitions. However, they are all used to resolve definition conflicts and determine the inheritance relationships of codes.

Security domains are independent of each other. In contrast, the relationship between application domains is more complex. Application domains are linked together through hierarchical relationships similar to the display list in flash. An application domain can contain any subdomain, and a subdomain can have only one parent domain. The subdomain inherits the definition from the parent domain, just like displaying the position of the parent object in the list and inheriting the zoom property quilt object.

The root node of the application domain is a system domain, which contains the native definition of the Flash Player API (array, XML, Flash. display. Sprite, etc ). The system domain corresponds to the security domain. When the security domain is initialized, this unique system domain is also created.

When a flash player instance is initialized, the SWF file is added to its corresponding security domain. At the same time, an application domain that contains all the compiled ActionScript definitions in this file is created. This application domain becomes the first subdomain of the System domain under the security domain. The native definition of the Flash Player API is open to all subdomains through this inheritance relationship.


A new SWF application domain is created in the system domain.

We will discuss inheritance in the inheritance section of the application domain.

Application domain placement application domain location

The definition contained in the SWF file of the first flash player instance is always loaded as a direct subdomain of the System domain. When a parent SWF loads a sub-SWF, it can control the position of the definition in the sub-SWF. There are four optional positions:

  1. Create a subdomain for the application domain of the parent SWF (default mode)
  2. Merge application domains of sub-SwF and parent SWF
  3. Create a subdomain under the System domain of the parent domain
  4. Create a subdomain for the System domain in another security domain

In the first three cases, the sub-SwF is loaded to the security domain where the parent domain is located. The fourth is the only method to load the SWF to other security domains.


Four options for placing application domains when loading sub-SwF

There is also another way not mentioned, that is, when you create an application domain for a loaded SWF and then merge the definitions in other sub-SwF into (or inherit from) this domain. This special placement method requires complex application domain level management, and you need to master applicationdomain. the usage of parentdomain reminds readers that this method usually has different behaviors in different security sandboxes (local or network. This method is uncommon, so we will not discuss it further here.

The applicationdomain attribute of the loadercontext object defines how to place the application domain. You can use applicationdomain. currentdomain (similar to securitydomain. currentdomain of the security domain) or use the new keyword to create an applicationdomain instance as the parameter. In the applicationdomain constructor, you can specify a parent domain for the newly created domain. If this parameter is not specified, the domain is directly used as a subdomain of the System domain.

// Place the definition in the application domain (current application domain) where the parent SWF is located var current: applicationdomain = applicationdomain. currentdomain; // the subdomain var currentchild: applicationdomain = new applicationdomain (current) where the parent SWF is located. <em>? </Em> // The System domain var systemchild: applicationdomain = new applicationdomain () that is defined to be placed in the application domain where the parent SWF is located ();

The following code demonstrates how to use the loadercontext object to pass the applicationdomain instance to the loader. Load Method and load a sub-SwF to the subdomain of the application domain in which the parent SWF is located. This method is also the default loading behavior.

VaR context: loadercontext = new loadercontext (); // use the subapplication domain as the subdomain of the current application domain var current: applicationdomain = applicationdomain. currentdomain; context. applicationdomain = new applicationdomain (current); var Loader: loader = new loader (); var URL: String = "child.swf"; loader. load (New URLRequest (URL), context );

The applicationdomain instance contains hierarchical location information that is not open to ActionScript. Each applicationdomain instance is a unique reference and cannot be compared with each other.

var current1:ApplicationDomain = ApplicationDomain.currentDomain;var current2:ApplicationDomain = ApplicationDomain.currentDomain;trace(current1 == current2); // false

You cannot get the reference of the System domain through the parentdomain attribute either. Only New applicationdomain () can be used.

Application domain inheritance application domain inheritance

The inheritance of definitions is a bit similar to that of class inheritance. Both are child-level definitions that can access the parent-level, but not vice versa.

The difference is that the inheritance of application domains does not allow the child level to overwrite the parent level definition. If the sub-domain contains the same definition as the parent domain (the fully qualified name is the same, including the package path ). The definition in the parent domain replaces the subdomain.


The definition in the subdomain is overwritten by the parent domain.

This is because you cannot change the class definition of an existing instance. If the new definition has already been used to generate an instance before it is loaded, the original class definition of the Instance conflicts with the new class definition. Therefore, Flash Player protects the original class definition from being overwritten to avoid conflicts.

This also means that developers cannot overwrite the native definition of the ActionScript API. Because the SWF application domain must be a subdomain of the System domain, and the system domain contains all native definitions. Therefore, even if the sub-SwF contains a definition of the same name, it will be overwritten by the definition in the system domain.

The preceding rules also apply when you merge definitions into an existing application domain. Only definitions that do not conflict with the definitions in the original domain will be merged.


The Definition added to the application domain does not overwrite the existing definition.

In this case, definitions that conflict but are overwritten cannot be obtained completely. However, if it is an inheritance method, even if the conflicting definitions in the subdomain are overwritten by the definitions in the parent domain, the getdefinition method can still be used to extract them from the subdomain, this will be discussed in the dynamic definition acquisition chapter.

Definitions loaded into the application domain exist throughout the life cycle of the application domain. After the SWF is detached, the application domain used to save the definition in the SWF will also be detached from the memory. However, if the SWF definition is placed in another existing application domain, these definitions will always exist in the memory, unless the SWF associated with the target application domain is uninstalled. If a new definition is always loaded into an existing domain, such as the domain created for the first loaded SWF, the memory occupied by the definition will continue to increase. If it is a rolling ad application that constantly loads sub-SWF, the memory growth problem caused by the continuous increase in the definition to the same application domain is obviously not the expected result.

In addition, the definition loaded in this way will not be detached with the sub-SWF, but will reuse the definition created during the first loading when the same sub-SwF is loaded for the second time. This is usually not a problem, but it means that when the same SWF is loaded again, the status of the static class will not be reset. Static variables may be the values used last time. They must be consistent with the values when they are loaded for the first time.

Therefore, different solutions are required in different situations.

Child Domains: Definition versioning subdomain: defined version management

The defined Inheritance mechanism allows the subdomain to easily share the definition of the parent domain. Also, because the cognominal definition in a subdomain is overwritten by the parent domain, the parent application domain has the right to control which version of the definition is used in the subdomain.


Child application domain inherited from parent domain

Consider the following situation: a SWF-based website uses different SWF files to represent different pages. The primary SWF is responsible for loading these subpages. Each page SWF is developed based on the same class library and has similar behavior. For example, there is a pagetitle class to indicate the title Text of the page.

If there is another SWF in the same domain, these same subpages are also used, but the title text of the subpage needs to be changed to optional (assuming that the original attribute is optional ). To achieve the purpose in this example, In the pagetitle class, we need to change the selectable attribute of textfield to false. However, this change will affect the original behavior of the SWF file.

To solve this problem, we can copy and recompile each sub-page. However, this will occupy more space and website traffic. A better way is to compile only the second primary SWF and compile the updated pagetitle class definitions together. Then, when the child page is loaded to the Child application domain, the definition of this class will be overwritten by the definition in the parent domain.

The pagetitle class used for all previous subpages is as follows:

package {import flash.display.Sprite;import flash.text.TextField; public class PageTitle extends Sprite { private var title:TextField; public function PageTitle(titleText:String){title = new TextField();title.text = titleText;addChild(title);}}}

The updated pagetitle class compiled into the second main file:

package {import flash.display.Sprite;import flash.text.TextField; public class PageTitle extends Sprite { private var title:TextField; public function PageTitle(titleText:String){title = new TextField();title.text = titleText;<strong>title.selectable = false;</strong> // changedaddChild(title);}}}

Compile the updated pagetitle class definition into the new main file and load all the sub-pages to their own sub-application domains.

Pagetitle; // although pagetitle is not directly used, we can include a reference, compile it together. // load the subpage to their own subapplication domain. // load the SWF. Replace the built-in function addchildpage with the pagetitle definition in the parent domain. (URL: string): void {var context: loadercontext = new loadercontext (); var current: applicationdomain = applicationdomain. currentdomain; context. applicationdomain = new applicationdomain (current); var Loader: loader = new loader (); addchild (loader); loader. load (New URLRequest (URL), context );}

This method can change the class behavior without re-compiling the child content. This is because the definition in the parent application domain will overwrite the definition in the subdomain.

Note that the use of loadercontext can be omitted in the above example, and the effect is the same.

Even if the sub-SwF does not need to be used for multiple purposes, updating the definitions in the master file is easier than updating all the sub-files. In fact, sub-files may not even include these definitions at all, but only rely on the provision of the main file. This will be discussed in the share library chapter for the same domain: runtime.

Separate domains: preventing conflicts domain separation: avoid conflict

In some cases, you may not want to load the sub-SwF content to be affected by the defined inheritance relationships in the parent application domain. Because you may not even know what definitions exist in the parent domain. In either case, it is best to avoid sharing the definitions in the primary SWF and sub-SWF. In this case, the sub-SwF definition should be placed under the subdomain of the new system domain.


Different sub-application domains in the system domain

Because there is no inheritance relationship between the parent SWF and the sub-SwF definition, even if the same definition exists, the two are different sandboxes.

For example, you have a training program that loads external SWF to represent different training modules. This program has been around for years and many developers have developed hundreds of training modules. These modules, and even the training main program itself, are developed based on different versions of the basic code library. Therefore, the main program must ensure that its own basic code library does not cause incompatibility with other modules. In this case, these training modules must be loaded into the subdomains in their independent system domains, rather than the subdomains in the primary application domains.

Trainingapplication.swf:

VaR moduleloader: loader = new loader (); addchild (moduleloader); // load the module to the subdomain of the System domain and distinguish it from the current application domain. Function loadmodule (URL: string): void {var context: loadercontext = new loadercontext (); context. applicationdomain = new applicationdomain (); moduleloader. load (New URLRequest (URL), context );}

However, this definition is not completely isolated. Because the content in the same security domain is in the same system domain, any modifications made to the system domain will affect all application domains in the same security domain. Even if the sub-SwF is loaded to a single sub-domain of the System domain, the change of the parent SWF to the system domain will still affect it.

We can verify this by modifying the XML. prettyindent attribute: No matter which SWF at the application domain level changes the definition in the system domain, it will affect all files in the same security domain.

Parent.swf:

Trace (XML. prettyindent); // 2xml. prettyindent = 5; trace (XML. prettyindent); // 5 var Loader: loader = new loader (); var context: loadercontext = new loadercontext (); // create an independent application domain context. applicationdomain = new applicationdomain (); var URL: String = "child.swf"; loader. load (New URLRequest (URL), context );

Child.swf:

trace(XML.prettyIndent); // 5

Therefore, the best practice is to restore the definition changes in time after use, so as to avoid the impact on other files.

var originalPrettyIndent:int = XML.prettyIndent;XML.prettyIndent = 5;trace(myXML.toXMLString());XML.prettyIndent = originalPrettyIndent;

Similarly, you must be aware that values like this may be changed outside of your program.

Same domain: runtime shared libraries same domain: runtime shared library

Adding a new definition to an existing application domain may be the greatest use of the application domain. Because inheritance can only share the definition of the parent domain with the subdomain, and merge the definition into the same application domain can share the SWF of all the use of this domain, including the parent and child.


Parent application domain includes the definition of sub-SwF

RSLs uses this mechanism. RSLs is an independent code library that can be loaded at runtime. Through RSLs, other SWF can share the code without compiling itself, eliminating redundancy, reducing the amount of files, and making the code easier to maintain. We load RSL in the main application domain to share the definition in the whole program.

Make preparations before using RSLs. First, the ActionScript compiler needs to know which definitions do not need to be compiled when publishing the SWF file.

Native Flash Player API definition does not need to be compiled. Although each SWF needs native definitions (such as array, XML, and sprite), these definitions only exist in the executable files of Flash Player, it does not need to be compiled into the SWF file. The compiler uses a special SWC (precompiled SWF class library) called playerglobal. SWC to identify native definitions. It contains native defined interfaces, including the defined names and data types. The compiler uses it to compile SWF without compiling these definitions into the final SWF.

The compiler can also reference other SWC libraries similar to playerglobal. SWC. These libraries are used as "external" class libraries. The definitions contained in these libraries are only for compilation and are not included in SWF.

Here we will not discuss in detail how to set the Library link in the editing tool. Different versions of the editor have different settings. For details, refer to the Flash document.

Although we use swcs to compile SWF, they are actually SWF files, similar to other loaded SWF Content. Both SWF and SWC files are generated during library compilation. SWF is used for load during runtime, while SWC is used as an external library during compilation.


The compiler uses the swcs shared library, and the SWF shared library is loaded at runtime.

Another preparation task requires coding. When using an external library, the published SWF does not contain the definition in the library. If Flash player tries to run the code, it will generate a verification error, and the entire SWF will basically be paralyzed.

Flash Player verifies its definition when the class is used for the first time. If this definition is not included in the application domain, validation errors are generated.

In fact, there are two errors caused by lack of definitions. Check errors are the worst of the two types, indicating that the class fails to work normally. The other is a reference error, which occurs when a data type is referenced But unavailable. Although missing definitions can cause reference errors, such errors only interrupt the normal process of code execution within the verified class.

VaR instance: doesnotexist; // verifyerror: Error #1014: Class doesnotexist cocould not be found. // when Flash Player verifies a class containing this definition, a verification error occurs.
VaR instance: Object = new doesnotexist (); // referenceerror: Error #1065: Variable doesnotexist is not defined. // a reference error occurs when the Code executes this line.

The main difference is that the verification error is related to the class definition, and the reference error is related to code execution. Before the code inside the class is executed, it must pass the verification first. In the above example, the instance object is declared as the object type, and the verification can pass normally (only a reference error occurs during execution ).

Note: strict mode Note: strict Mode

An external library references a definition without compiling it into SWF. Another way is to disable the strict mode, which will greatly relax the check on variable usage. For the use of classes, you can reference a non-existent class without causing the compiler to report errors. You cannot directly use a non-existent class as the variable type (this will generate a verification error at runtime), but you can reference it as in the above "reference error" example. In non-strict mode, the compiler may not detect some possible errors, so this mode is generally not recommended.

The SWF file that uses RSLs must be loaded before these external definitions can be used. We should use a pre-loader to load RSLs before the main application starts to execute.

The following example shows how to load an external RSL containing the doughnut class in SWF. Although this class is directly referenced in SWF, It is compiled in the external library and referenced through SWC. RSL is loaded before the doughnut class is used for the first time, so no validation error is caused.

Doughnut.(CompileDoughnutlibrary. SWCAndDoughnutlibrary.swf):

package {import flash.display.Sprite; public class Doughnut extends Sprite {public function Doughnut(){ // draw a doughnut shapegraphics.beginFill(0xFF99AA);graphics.drawCircle(0, 0, 50);graphics.drawCircle(0, 0, 25);}}}

Shapesmain.(Primary class of shapes.swf):

Package {import flash. display. sprite; public class shapesmain extends sprite {public function shapesmain () {// although not compiled into shapes.swf, // but we use doughnutlibrary. SWC External library // you can obtain a reference to the doughnut class var donut: doughnut = new doughnut (); donut. X = 100; donut. y = 100; addchild (donut );}}}

Shapes.swf(RSL loader ):

VaR rslloader: loader = new loader (); rslloader. contentloaderinfo. addeventlistener (event. init, rslinit); // load the definition in rsl to the current application domain var context: loadercontext = new loadercontext (); context. applicationdomain = applicationdomain. currentdomain; var URL: String = "doughnutlibrary.swf"; rslloader. load (New URLRequest (URL), context); function rslinit (Event: Event ): void {// only after the definitions in rsl are imported to the current application domain can we use the doughnut definition to verify addchild (New shapesmain () through the shapesmain class ());}

In this example, shapes.swf is the main program, and the shapesmain class is instantiated after RSL is loaded. If the definition in rsl is not imported, a verification error occurs when the shapesmain instance is created because the corresponding class cannot be found in the application domain.

Note: RSL In Flex

The method discussed here is the underlying method and should not be used for flex development. The flex framework has its own RSLs processing mechanism. For more information about RSL applications in flex, see flex runtime shared libraries (Flex 4 ).

Getting definitions dynamically dynamic get Definition

We can use the application. getdefinition method to obtain definitions that are not in the application domain or that are overwritten by the parent domain. This method returns the definition reference of the application domain and any parent domain. Using the getdefinition method in the current application domain is equivalent to the global function getdefinitionbyname.

We can also use loaderinfo. applicationdomain of SwF to obtain application domains other than applicationdomain. currentdomain. In the following example, we load a SWF file with loader, and then extract the definition of the COM. example. Box class from the loaded application domain.

try {var domain:ApplicationDomain = loader.contentLoaderInfo.applicationDomain;var boxClass:Class = domain.getDefinition("com.example.Box") as Class;var boxInstance:Object = new boxClass();}catch(err:Error){trace(err.message);}

The preceding example contains two knowledge points. First, the return value of the getdefinition method is explicitly converted to the class type, because getdefinition returns the object type by default, which may represent other types except the class type (function, namespace, interface ). Second, this operation should be placed in the try-catch function, because if the getdefinition search definition fails, an error will be thrown. Alternatively, you can use the applicationdomain. hasdefinition method to check whether a definition can be found before getdefinition.

Definitions obtained in a dynamic manner, rather than those defined in the current application domain (and inherited application domain), cannot be used as variable types. Like RSL, class definitions that cannot be found in the application domain will report an error during verification. In the preceding example, the boxinstance variable is declared as the object type rather than the box type, because the definition of the box class does not exist in the application domain.

Same-definition collisions conflict with the same definition

Sometimes, the definitions you reference may match the definitions in another application domain. In this case, the following forced conversion type error occurs:

TypeError: Error #1034: Type Coercion failed: cannot convertcom.example::MyClass@51e1101 to com.example.MyClass.

You can see that the definitions in different memory spaces are distinguished by the @ symbol. Although their internal code may be identical (or different), they are two different definitions because they exist in different application domains (or security domains.

Only native Flash Player definitions like objects can be associated with definitions in different domains (or even cross-security domains. In fact, the object type is usually used to declare a cross-domain variable type.

Although we can use the generic type of object to solve the definition conflict error, we should arrange the location of the application domain to eliminate this mismatch.

Conclusion Summary

This tutorial contains a lot of information. The first half discusses what a security domain is and how it affects content from different domains. Flash Player uses this Security Sandbox mechanism to protect user data. Flash developers should understand and make rational use of such restrictions.

The second part discusses the application domain-another sandbox type that is used to divide the WordPress definition in the security sandbox. The hierarchical mechanism of application domains provides methods for directly sharing and reusing definitions in different SWF files.

There are many mistakes that are easy to make in terms of security domains and application domains. I hope this tutorial will help you prepare for this. You should not only understand how they work, but also how to use them correctly to achieve the desired effect.

Note:

Through the translation of this article, I realized the difficulty of translation work. Although reading English documents is still fast, it takes dozens of times to repeat it in Chinese. In the translation of this tutorial, I did not use full-text translation or other auxiliary tools. I tried to understand the author's intention. I feel more rewarding than simply reading it once.

The knowledge introduced in this article is very important. especially developers who have grown up in the as2 ERA can easily fall into some traps mentioned in this article. Full understanding of this part of knowledge is of great help in designing the module architecture and managing memory. I would like to thank the original author senocular for bringing us such a wonderful tutorial.

Please respect copyright and repost it with the source.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.