Android control hybrid binding method and system for adapting non-final resource IDs
Patent Information
- Application Number
- CN202611393839.5
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-09-09
- Publication Date
- 2026-10-30
AI Technical Summary
[0005]本申请提供一种适配非final资源ID的Android控件混合绑定方法及系统,旨在解决现有技术在Android控件实例化过程中,资源管理方式变化导致的控件关联兼容性不足、不同页面场景下处理效率与适应性难以兼顾、多模块工程中的控件关联容易相互影响以及异常控件和失效引用难以及时处理的问题
本申请基于对现有技术问题的进一步分析和研究,认识到现有技术在Android控件实例化过程中,资源管理方式变化导致的控件关联兼容性不足、不同页面场景下处理效率与适应性难以兼顾、多模块工程中的控件关联容易相互影响以及异常控件和失效引用难以及时处理的问题,通过获取目标Android工程中各工程模块的资源编译结果及目标类中各待绑定字段的控件绑定标记,确定各待绑定字段对应的编译期绑定类型或运行时绑定类型,并按照模块命名空间建立相互隔离的控件资源名称与控件资源ID之间的资源映射信息,使运行时绑定类型的待绑定字段能够以控件资源名称查询对应的控件资源ID,从而降低资源ID不满足编译期常量要求对控件绑定造成的影响,并减少不同工程模块之间的资源关联相互干扰;在此基础上,针对编译期绑定类型的待绑定字段调用预先生成的编译期绑定代码直接完成控件查找与字段赋值,能够降低静态布局场景下的运行处理开销,针对运行时绑定类型的待绑定字段则利用资源映射信息查找控件实例并通过反射完成字段赋值,能够适应控件资源关系需要在运行阶段确定的页面场景,由此兼顾控件绑定的处理效率与场景适应性;同时,在反射赋值前执行空值校验和字段类型匹配校验,并在单个待绑定字段发生反射赋值异常时终止当前字段的绑定处理而继续处理其他字段,能够将异常影响限制在当前字段,避免局部绑定失败影响页面整体运行;进一步地,通过监测页面或视图的生命周期状态,在页面或视图销毁时清空已绑定字段中的控件实例引用并释放相关联信息,能够减少失效控件引用造成的内存占用,因此能够提高Android控件绑定对资源管理方式变化和不同页面场景的兼容能力,降低多模块工程中的绑定干扰,并提升控件绑定过程的执行效率、异常容错能力及运行稳定性。
Smart Images

Figure CN123011232A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of Android development technology, and in particular to a method and system for hybrid binding of Android controls that adapts to non-final resource IDs. Background Technology
[0002] With the development of mobile terminal technology, Android applications are carrying increasingly more business functions. Application interfaces typically consist of various controls such as text display, information input, function buttons, list displays, and custom views. During Android application development, controls in the layout file need to be associated with corresponding objects in the program code so that the program can perform operations such as data setting, state updating, event handling, and interactive control of the controls. Therefore, the acquisition and management of control objects is a fundamental aspect of Android application interface development, and its processing efficiency and reliability affect the development, maintenance, and operational stability of the application.
[0003] In existing technologies, developers typically search for control objects one by one based on their resource identifiers, or use automated tools to associate controls with program fields. Searching for control objects one by one requires writing a lot of repetitive code, and as the number of page controls increases, issues such as missing controls, incorrect resource references, or mismatched object types can easily occur. Existing automated processing methods can reduce repetitive operations to some extent, but different methods often prioritize processing efficiency or flexibility, making it difficult to adapt to different types of pages and project environments. Furthermore, with changes in Android development tools, resource management methods, and project organization, some automated processing methods may encounter problems such as difficulty in correctly obtaining resource information, failed control associations, or increased runtime overhead. In application projects containing multiple business modules, there may also be situations where information is duplicated between different modules or processing results affect each other. In addition, the existing control association process has limited fault tolerance for situations such as controls not found, abnormal object types, and errors in the processing. Residual control references after the page exits may also increase memory usage and affect the stability of application operation.
[0004] Therefore, during the instantiation of Android controls, the following issues urgently need to be addressed: insufficient compatibility of control associations due to changes in resource management methods; difficulty in balancing processing efficiency and adaptability in different page scenarios; easy mutual interference of control associations in multi-module projects; and difficulty in timely handling of abnormal controls and invalid references. Summary of the Invention
[0005] This application provides a method and system for hybrid binding of Android controls that adapts to non-final resource IDs. It aims to solve the problems of insufficient compatibility of control associations caused by changes in resource management methods during the instantiation of Android controls, difficulty in balancing processing efficiency and adaptability in different page scenarios, easy mutual interference of control associations in multi-module projects, and difficulty in timely handling of abnormal controls and invalid references.
[0006] Firstly, a method for hybrid binding of Android controls that adapts to non-final resource IDs, the method comprising: Obtain the resource compilation results of each project module in the target Android project and the control binding mark corresponding to each field to be bound in the target class. Determine the binding type and control resource information of each field to be bound based on the control binding mark. The binding type includes compile-time binding type and runtime binding type. The control resource information corresponding to the runtime binding type includes the control resource name. According to the module namespace of each project module, the control resource name and control resource ID in the resource compilation result are associated, and the isolated resource mapping information corresponding to each project module is generated respectively. The corresponding compile-time binding code is generated for the fields to be bound for the compile-time binding type, and the association relationship between the target class and the corresponding compile-time binding code and resource mapping information is established. In response to a control binding request for a target object to be bound, the root view corresponding to the target object to be bound is obtained, wherein the target object to be bound is an object instance of the target class, and the corresponding control binding process is performed according to the binding type of each field to be bound; For the field to be bound of the compile-time binding type, the corresponding compile-time binding code is called to directly find the corresponding control instance from the root view and assign the control instance to the field to be bound; For the field to be bound in the runtime binding type, the resource mapping information is queried according to the project module to which the target object to be bound belongs and the corresponding control resource name to obtain the corresponding control resource ID, and the corresponding control instance is found from the root view according to the control resource ID; Null value validation and field type matching validation are performed on the control instance found for the runtime binding type. When the validation passes, the control instance is assigned to the corresponding field to be bound via reflection. If the reflection assignment of the current field to be bound fails, the binding process of the current field to be bound is terminated and other fields to be bound are processed. Monitor the lifecycle state of the page or view corresponding to the target object to be bound, and when the page or view enters the destruction state, clear the control instance references in each bound field and release the association information saved during the binding process.
[0007] Optionally, in the above scheme, the step of associating the control resource names and control resource IDs in the resource compilation results according to the module namespace of each project module, and generating mutually isolated resource mapping information corresponding to each project module, includes: After the resources of the target Android project are compiled, the resource symbol information corresponding to each project module is parsed to obtain the module namespace, control resource type, control resource name and control resource ID corresponding to each control resource; The module namespace, control resource type, and control resource name corresponding to each control resource are combined to obtain the resource retrieval identifier corresponding to each control resource; Hash each resource retrieval identifier to obtain the corresponding mapping storage location; According to each mapping storage location, each resource retrieval identifier is associated with the corresponding control resource ID and stored to obtain the resource mapping information corresponding to each project module, so that control resources with the same control resource name in different project modules correspond to different resource retrieval identifiers.
[0008] Optionally, the above scheme may also include: Obtain the resource change information of the target Android project, and determine the target control resources that have been added, modified or deleted based on the resource change information to obtain the resource change set; Based on the module namespace corresponding to each target control resource in the resource change set, determine the resource mapping entries to be updated from the resource mapping information corresponding to each project module; Based on the change type corresponding to each target control resource, perform add, replace, or delete operations on the resource mapping entries to be updated to obtain the updated resource mapping entries; The updated resource mapping entries are written into the resource mapping information of the corresponding project module to obtain the incrementally updated resource mapping information.
[0009] Optionally, in the above scheme, generating corresponding compile-time binding code for the fields to be bound of the compile-time binding type, and establishing the association between the target class and the corresponding compile-time binding code and resource mapping information, includes: Parse the control binding tag corresponding to the compile-time binding type to obtain the field identifier, field type, and control resource information of the corresponding field to be bound; Based on the field identifier, the field type, and the control resource information, generate field binding code for finding control instances from the root view and assigning the control instances to the field to be bound; Based on the fully qualified class name of the target class and the module namespace of the project module to which the target class belongs, determine the binding class identifier corresponding to the target class, and generate the compile-time binding class corresponding to the target class based on the field binding code corresponding to each field to be bound; Associating the fully qualified class name of the target class, the module namespace, the binding class identifier, and the corresponding resource mapping information identifier generates a module binding index corresponding to the project module to which the target class belongs.
[0010] Optionally, in the above scheme, the step of performing corresponding control binding processing according to the binding type of each field to be bound includes: Based on the type information of the target object to be bound, obtain the field binding information that is pre-associated with the target class. The field binding information includes the binding type and control resource information of each field to be bound. Based on the binding type of each field to be bound, the fields to be bound are divided into a set of compile-time bound fields and a set of runtime bound fields; The corresponding compile-time binding code is invoked for the aforementioned compile-time bound field set to obtain the compile-time field binding results; Perform resource mapping query and control instance lookup on the set of runtime binding fields to obtain candidate control instances corresponding to each runtime binding field; Runtime field assignment processing is performed based on the candidate control instance to obtain the runtime field binding result. The compile-time field binding result and the runtime field binding result are then summarized to obtain the control binding result corresponding to the target object to be bound.
[0011] Optionally, in the above scheme, the step of performing resource mapping query and control instance lookup on the set of runtime binding fields to obtain candidate control instances corresponding to each runtime binding field includes: Sequentially obtain the control resource name and control resource type corresponding to each field to be bound in the runtime binding field set, and obtain the module namespace of the project module to which the target object to be bound belongs; The module namespace, the control resource type, and the control resource name are combined to obtain the resource query identifier corresponding to each field to be bound; The resource query identifier is used to query the resource mapping information of the corresponding project module to obtain the control resource ID corresponding to each field to be bound; Based on the resource ID of each control, the corresponding control instance is found in the root view to obtain the candidate control instance corresponding to each field to be bound.
[0012] Optionally, in the above scheme, the step of performing runtime field assignment processing based on the candidate control instance to obtain the runtime field binding result includes: Determine whether each candidate control instance is empty, and obtain the null value verification result for each candidate control instance; For candidate control instances whose null value validation result indicates that they are not null, determine whether the actual type of the candidate control instance belongs to the preset set of bindable control types, and determine whether the actual type of the candidate control instance and the field type of the corresponding field to be bound satisfy the assignable relationship, and obtain the type validation result; For candidate control instances whose type validation results indicate that the validation has passed, access permissions are granted to the corresponding fields to be bound, and the candidate control instances are assigned to the corresponding fields to be bound via reflection to obtain the reflection assignment result. For the field to be bound that indicates a successful assignment result from the reflection assignment, the binding association information between the target object to be bound, the field to be bound, and the corresponding control instance is saved in the form of a weak reference to obtain a successful binding record; For fields to be bound that are empty, fail type validation, or have an error during reflection assignment, a binding failure record containing information about the field to be bound, control resource information, and the reason for failure is generated. The binding process of the current field to be bound is terminated, and the next field to be bound is processed to obtain the runtime field binding result.
[0013] Optionally, in the above scheme, monitoring the lifecycle state of the page or view corresponding to the target object to be bound, and clearing the control instance references in each bound field and releasing the association information saved during the binding process when the page or view enters the destruction state, includes: Based on the object type of the target object to be bound, determine the lifecycle subject and target destruction event corresponding to the target object to be bound. The lifecycle subject includes the lifecycle subject corresponding to the Activity object or the lifecycle subject corresponding to the Fragment view. Register a lifecycle listener based on the lifecycle subject, and associate the lifecycle listener with the binding association information to obtain the lifecycle binding relationship; The lifecycle listener acquires lifecycle events generated by the lifecycle subject, and when the lifecycle event matches the target destruction event, the set of fields to be unbound is determined according to the lifecycle binding relationship. The target object to be bound is obtained based on the binding association information, and the control instance references of each field to be bound in the set of fields to be unbound are cleared. The binding association information corresponding to each field to be bound is deleted, and the unbinding result corresponding to the target object to be bound is obtained.
[0014] Optionally, in the above scheme, the step of responding to a control binding request for a target object to be bound, obtaining the root view corresponding to the target object to be bound, and performing corresponding control binding processing according to the binding type of each field to be bound includes: Obtain the fully qualified class name of the target object to be bound and the module namespace of the project module to which the target object to be bound belongs, and obtain the target class identifier and the target module identifier; Based on the target class identifier and the target module identifier, the module binding index is queried to obtain the binding class identifier and resource mapping information identifier corresponding to the target object to be bound; Load the corresponding compile-time binding class according to the binding class identifier, and load the resource mapping information of the corresponding project module according to the resource mapping information identifier, to obtain the binding execution information corresponding to the target object to be bound; The compile-time binding class is invoked based on the root view and the binding execution information, and the unbound fields of the runtime binding type are processed using the resource mapping information to obtain the control binding result corresponding to the unbound target object.
[0015] Secondly, an Android control hybrid binding system adapted to non-final resource IDs, the system comprising: The binding information acquisition module is used to acquire the resource compilation results of each project module in the target Android project and the control binding mark corresponding to each field to be bound in the target class. Based on the control binding mark, the binding type and control resource information of each field to be bound are determined. The binding type includes compile-time binding type and runtime binding type. The control resource information corresponding to the runtime binding type includes the control resource name. The compilation processing module is used to associate the control resource name and control resource ID in the resource compilation result according to the module namespace of each project module, generate mutually isolated resource mapping information corresponding to each project module, generate corresponding compile-time binding code for the fields to be bound for the compile-time binding type, and establish the association relationship between the target class and the corresponding compile-time binding code and resource mapping information. The hybrid binding module is used to respond to control binding requests for target objects to be bound, obtain the root view corresponding to the target object to be bound (the target object is an object instance of the target class), and perform corresponding control binding processing according to the binding type of each field to be bound. For fields to be bound of the compile-time binding type, the corresponding compile-time binding code is called to directly find the corresponding control instance from the root view and assign the control instance to the field to be bound. For fields to be bound of the runtime binding type, the resource mapping information is queried according to the project module to which the target object to be bound belongs and the corresponding control resource name to obtain the corresponding control resource ID, and the corresponding control instance is found from the root view according to the control resource ID. The security processing module is used to perform null value validation and field type matching validation on the control instance found for the runtime binding type. When the validation passes, the control instance is assigned to the corresponding field to be bound via reflection. When the reflection assignment of the current field to be bound fails, the binding process of the current field to be bound is terminated and other fields to be bound are processed. The lifecycle management module is used to monitor the lifecycle status of the page or view corresponding to the target object to be bound, and when the page or view enters the destruction state, it clears the control instance references in each bound field and releases the association information saved during the binding process.
[0016] Compared with the prior art, this application has at least the following beneficial effects: This application, based on further analysis and research of existing technical problems, recognizes that existing technologies suffer from several issues during Android control instantiation, including insufficient control association compatibility due to changes in resource management methods, difficulty in balancing processing efficiency and adaptability across different page scenarios, easy mutual interference between control associations in multi-module projects, and difficulty in timely handling of abnormal controls and invalid references. By obtaining the resource compilation results of each module in the target Android project and the control binding markers of each field to be bound in the target class, the compile-time binding type or runtime binding type corresponding to each field to be bound is determined. Furthermore, resource mapping information between isolated control resource names and control resource IDs is established according to the module namespace. This allows the field to be bound for runtime binding types to query the corresponding control resource ID by the control resource name, thereby reducing the impact of resource IDs not meeting compile-time constant requirements on control binding and minimizing mutual interference between resource associations of different project modules. Based on this, for the field to be bound for compile-time binding types, pre-generated compile-time binding code is called to directly complete the control binding. The lookup and field assignment functions reduce runtime processing overhead in static layout scenarios. For fields to be bound at runtime, resource mapping information is used to find control instances and field assignment is completed via reflection. This adapts to page scenarios where control resource relationships need to be determined at runtime, thus balancing control binding efficiency with scenario adaptability. Furthermore, null value validation and field type matching validation are performed before reflection assignment. If a reflection assignment exception occurs in a single field to be bound, the binding process for that field is terminated while other fields are processed. This limits the impact of exceptions to the current field, preventing partial binding failures from affecting the overall page operation. Moreover, by monitoring the lifecycle state of the page or view, control instance references in bound fields are cleared and associated information is released when the page or view is destroyed. This reduces memory usage caused by invalid control references. Therefore, it improves the compatibility of Android control binding with changes in resource management methods and different page scenarios, reduces binding interference in multi-module projects, and enhances the execution efficiency, exception tolerance, and operational stability of the control binding process. Attached Figure Description
[0017] Figure 1 This is a flowchart illustrating an embodiment of the Android control hybrid binding method adapted to non-final resource IDs provided in this application. Detailed Implementation
[0018] To make the objectives, technical solutions, and advantages of this application clearer, the following detailed description is provided in conjunction with the accompanying drawings and embodiments. It should be understood that the specific embodiments described herein are merely illustrative and not intended to limit the scope of this application.
[0019] In one embodiment, such as Figure 1 As shown, a method for hybrid binding of Android controls that adapts to non-final resource IDs is provided. This method can be applied to Android applications built using Java or a development language compatible with the Java Virtual Machine. The target Android project may include application modules and one or more business modules, basic modules, or functional component modules, each with its own module namespace. The target class can be an Activity class, Fragment class, Dialog class, ViewHolder class, or other classes that require obtaining layout controls. The target object to be bound is an instance of the target class formed during application runtime.
[0020] During the development phase of a target Android project, developers can set control binding markers on fields to be bound in the target class. Control binding markers are used to characterize the binding type and control resource information of the corresponding field. Binding types include compile-time binding types and runtime binding types. Compile-time binding types are suitable for static layout scenarios where the layout structure and control resource relationships can be determined during the compilation phase; runtime binding types are suitable for non-final resource IDs, dynamic layouts, conditionally loaded layouts, or other scenarios where control resource IDs need to be determined during application runtime.
[0021] Control binding can be implemented using annotations. For example, the control binding markup for compile-time binding types can use the `@BindViewCompile` annotation, while the control binding markup for runtime binding types can use the `@BindViewRuntime` annotation. The `@BindViewCompile` annotation can use a CLASS-level retention strategy, parsed by the annotation processing component during the compile-time phase; the `@BindViewRuntime` annotation can use a RUNTIME-level retention strategy, so that the corresponding annotation information can be obtained during runtime. The control resource information corresponding to the runtime binding type must at least include the control resource name, such as `tv_title` or `btn_submit`, thus avoiding directly using non-final resource IDs as parameters for runtime control binding marks.
[0022] During the construction of the target Android project, the resource compilation results of each project module are first obtained. These results can originate from resource symbol files, resource symbol tables, merged resource lists, or other data reflecting the correspondence between control resource names and control resource IDs, as output by the Android resource packaging tool. The resource compilation results must include at least the control resource name, control resource type, and control resource ID, where the control resource type is, for example, the id type.
[0023] Simultaneously, the annotation processing component scans the fields to be bound in the target class, parses the control binding tags corresponding to each field, and obtains the field identifier, field type, binding type, and control resource information. The field identifier can be the field name, and the field type can be TextView, Button, ImageView, RecyclerView, or other subclasses of View. The parsing results are then stored in a structured manner to obtain the field binding information corresponding to each target class.
[0024] After obtaining the resource compilation results, the control resource names are associated with their corresponding control resource IDs according to the module namespaces of each project module, thus obtaining the resource mapping information for each project module. Resource mapping information can be implemented using hash maps, array index tables, key-value index files, or static mapping structures in the generated code. The resource mapping information uses the module namespace as the isolation boundary, thereby ensuring that control resources with the same name in different project modules have independent mapping relationships.
[0025] For fields of compile-time binding type, the annotation processing component generates corresponding compile-time binding code based on the field identifier, field type, and control resource information. The compile-time binding code includes code for finding control instances in the root view and code for directly assigning the found control instances to the fields to be bound. For multiple fields of the same target class, the compile-time binding code for multiple fields can be encapsulated in the same compile-time binding class.
[0026] Compile-time binding classes generate unique identifiers based on the fully qualified class name of the target class and the module namespace of the project module to which the target class belongs. For example, a preset binding suffix can be added after the target class name to form the corresponding binding class name. Different project modules generate their own compile-time binding classes and resource mapping information, and are physically isolated through module namespaces, thereby avoiding duplicate class names, overridden generated code, or incorrect resource references during multi-module annotation processing.
[0027] After generating compile-time binding code and resource mapping information, the association between the target class, compile-time binding code, and resource mapping information is established. This association can be recorded in the module binding index or generated in the module-level binding entry class. During runtime, the corresponding compile-time binding class and resource mapping information can be quickly determined based on the type of the target object to be bound and its project module.
[0028] During application runtime, once an Activity completes its layout setup, a Fragment completes its view creation, or another target class obtains its root view, it sends a control binding request to the hybrid binding engine. The control binding request can include the target object to be bound and the root view. The root view is used to limit the search scope of control resource IDs, avoiding searching for control instances in the wrong view hierarchy.
[0029] The hybrid binding engine retrieves the corresponding field binding information based on the type information of the target object to be bound, and performs the appropriate control binding processing according to the binding type of each field. For fields with compile-time binding types, the hybrid binding engine calls the corresponding compile-time binding code, directly finds the control instance from the root view based on the control resource ID, and assigns the control instance to the field to be bound through generated code. This process does not require field reflection to complete the assignment.
[0030] For fields to be bound at runtime, the hybrid binding engine obtains the module namespace of the project module to which the target object belongs and the control resource name corresponding to the field to be bound. Based on the module namespace and control resource name, it queries the corresponding resource mapping information to obtain the corresponding control resource ID. Subsequently, it calls the control lookup interface of the root view based on the control resource ID to obtain the corresponding control instance.
[0031] Before assigning values to fields at runtime, null value validation and field type matching validation are performed on the control instance. Null value validation is used to determine whether the control instance can be found in the root view based on the control resource ID; field type matching validation is used to determine whether the actual type of the control instance can be assigned to the field type of the field to be bound. The reflection assignment process only begins when the control instance is not null and the field type matches.
[0032] During reflection assignment, access permissions for the fields to be bound can be enabled, and control instances can be assigned to the corresponding fields in the target object. Reflection operations only target the fields to be bound within the target class itself, without calling restricted private interfaces of the Android system, thus reducing the impact of private API controls on the binding process in higher versions of Android.
[0033] Reflection assignment employs a field-level exception circuit breaker. When an unbound field encounters an illegal access, type conversion exception, missing control resource, or other reflection exception, the exception corresponding to the currently unbound field is caught, the binding process for that field is terminated, the field information, control resource information, and the reason for failure are recorded, and other unbound fields are then processed. The exception for the currently unbound field is not thrown further into the page call chain, thus preventing the entire page from crashing due to a single control binding failure.
[0034] After binding is complete, the binding association information between the target object to be bound, the bound fields, and the control instances is established, and the lifecycle state of the page or view corresponding to the target object to be bound is monitored. For Activity objects, the destruction event corresponding to the Activity can be monitored; for view fields in Fragment objects, the destruction event corresponding to the Fragment view can be monitored. When the page or view enters the destruction state, the references to control instances in each bound field are cleared, and the binding association information saved during the binding process is released.
[0035] For example, in an Activity, the title field can have a compile-time bound control binding flag set, while the submit button field can have a runtime bound control binding flag set. After the page starts, the title field is directly assigned a value by the compile-time bound code, while the submit button field queries the resource mapping information based on the resource name `btn_submit` to obtain the corresponding control resource ID, and then assigns a value via reflection after performing null value and type validation. When the page is destroyed, the control instance references in both fields are cleared.
[0036] Through the above processing, non-final resource IDs can be adapted using control resource names and module-level resource mapping information. A combination of compile-time binding and runtime binding balances the processing efficiency of static layout with the adaptability of dynamic layout. Module namespaces reduce the mutual interference between resources from multiple modules and generated code. Furthermore, validation, field-level exception circuit breaking, and lifecycle unbinding improve the stability of the control binding process and reduce memory consumption caused by invalid references. In some test environments, compared to control binding methods that rely entirely on runtime reflection, compile-time binding for static layout controls can improve page startup speed by more than 30%, with the specific improvement varying depending on device performance, the number of page controls, and project size.
[0037] In one implementation, after the target Android project completes resource compilation, the resource symbol information corresponding to each project module is obtained. This resource symbol information can be obtained by reading the resource symbol file generated by the resource compilation tool, or it can be extracted by the build plugin after the resource merging or processing task is completed. By parsing the resource symbol information, the module namespace, control resource type, control resource name, and control resource ID corresponding to each control resource are obtained.
[0038] Module namespaces are used to identify the project module to which a control resource belongs. For example, application modules and business modules can be configured with different module namespaces. Control resource types are used to distinguish between ID resources, layout resources, string resources, or other resource types. In control binding scenarios, the control resource type is typically ID. The control resource name is the control name configured in the layout file, and the control resource ID is an integer identifier assigned after the resource is compiled.
[0039] The module namespace, control resource type, and control resource name corresponding to each control resource are combined in a preset order to obtain the corresponding resource retrieval identifier. For example, the resource retrieval identifier can be in the form of "module namespace: control resource type: control resource name". Separators can be set between different components of the resource retrieval identifier, or it can be converted into structured key-value pairs according to preset encoding rules.
[0040] By adding module namespaces to resource retrieval identifiers, even if two project modules contain the same control resource name, different resource retrieval identifiers can be generated based on the different module namespaces. Therefore, during runtime, when querying control resource IDs, the resource query scope can be limited to the project module to which the target object to be bound belongs.
[0041] Each resource retrieval identifier is hashed to obtain a corresponding hash value, and the mapping storage location is determined based on the hash value. A hash algorithm suitable for string key-value processing can be used. To reduce query overhead on mobile terminals, hash value calculation can be completed during the construction phase, and the calculation result can be written into the generated resource mapping information.
[0042] When different resource retrieval identifiers yield the same hash value, hash collisions can be handled using chaining, open addressing, or double-checking of the resource retrieval identifier. During runtime, candidate mapping entries are first located based on the hash value of the resource query identifier, and then the complete resource retrieval identifier is compared to obtain the accurate control resource ID.
[0043] Based on the storage location of each mapping, the resource retrieval identifier is associated with and stored with the corresponding control resource ID, forming the resource mapping information for each project module. The resource mapping information can be generated in different module package paths or encapsulated in different module resource index classes. The resource mapping information of each project module does not overwrite each other, and the module binding index records their corresponding relationships.
[0044] By constructing a resource retrieval identifier using module namespace, control resource type, and control resource name, incorrect matching of resources with the same name in different project modules can be avoided. By performing hash processing during the build phase, control resource IDs can be quickly determined during the runtime phase, reducing the processing overhead caused by string resource queries, thereby improving resource query efficiency while adapting to non-final resource IDs.
[0045] In one implementation, when layout files or control resources in the target Android project change, resource change information for the target Android project is obtained. This resource change information can be provided by the incremental compilation mechanism of the Android build system, or it can be obtained by comparing the current resource file state with a resource snapshot saved in the previous build cycle.
[0046] Based on resource change information, identify the target control resources that have been added, modified, or deleted, forming a resource change set. Newly added target control resources refer to control resources that appear for the first time in the current build cycle; modified target control resources may include resources whose names have changed, whose project modules have changed, or whose control resource IDs have been reassigned; deleted target control resources refer to control resources that existed in the previous build cycle but do not exist in the current build cycle.
[0047] For each target control resource in the resource change set, determine its corresponding module namespace. Based on the module namespace, locate the resource mapping information of the corresponding project module, and further determine the resource mapping entries to be updated based on the control resource type and control resource name.
[0048] For newly added target control resources, their module namespace, control resource type, and control resource name are combined into a new resource retrieval identifier. The new resource retrieval identifier is hashed, and the new resource retrieval identifier and the corresponding control resource ID are written into the resource mapping information of the corresponding project module to obtain the newly added resource mapping entry.
[0049] For the target control resource being modified, determine the resource retrieval identifier and control resource ID before and after the modification. When the resource retrieval identifier remains unchanged but the control resource ID changes, replace the control resource ID in the corresponding resource mapping entry; when the resource retrieval identifier changes, delete the original resource mapping entry and write a new resource mapping entry according to the modified resource information.
[0050] For the target control resource to be deleted, locate the corresponding resource mapping entry based on its original resource retrieval identifier, and delete the resource mapping entry from the resource mapping information of the corresponding project module to prevent the invalid control resource ID from being found during the runtime.
[0051] After completing the addition, replacement, or deletion operations for each target control resource, the updated resource mapping entries are written to the resource mapping information of the corresponding project module, resulting in incrementally updated resource mapping information. Other resource mapping entries that have not undergone resource changes remain unchanged, and there is no need to regenerate the resource mapping information for the entire project module.
[0052] To avoid reading incomplete data during the update process, temporary resource mapping information can be generated first during the build phase. After all resource changes for the current project module have been processed, the official resource mapping information can be updated using an atomic replacement method. Since the resource mapping information is mainly generated during the build phase and read during application runtime, it will not increase the resource update burden during page runtime.
[0053] By performing add, replace, or delete operations only on resource mapping entries that have changed, the amount of build processing during resource changes can be reduced. This avoids rescanning and generating all resource mapping information for each resource change, thereby improving the incremental compilation efficiency of large componentized Android projects and ensuring that the names of control resources used during runtime maintain a correct correspondence with the control resource IDs.
[0054] In one implementation, the annotation processing component during the compilation phase parses the control binding tags corresponding to the compile-time binding types to obtain the field identifier, field type, and control resource information for each field to be bound. The field identifier is used to locate the field to be bound in the target class, the field type is used to determine the type relationship between the control instance and the field to be bound, and the control resource information is used to determine the control instance to be searched in the root view.
[0055] Compile-time binding types are applicable to static layout controls whose layout structure can be determined during the build phase. In one alternative implementation, the compile-time control binding tag can receive a control resource ID that can be resolved during the build phase. In another alternative implementation, the compile-time control binding tag can receive a control resource name, and the annotation processing component determines the corresponding control resource ID based on the resource compilation result when generating compile-time binding code.
[0056] Based on the field identifier, field type, and control resource information, corresponding field binding code is generated. The field binding code includes calling the root view's control lookup interface based on the control resource ID, converting the found control instance to the field type, and directly assigning the converted control instance to the field to be bound. The field binding code may also include handling logic when the control instance is null and error message logic when the types do not match.
[0057] For multiple compile-time bound fields within the same target class, the field binding code for each field is combined to form a compile-time bound class for the target class. This compile-time bound class can include binding and unbinding methods. The binding method performs control lookup and field assignment based on the target object and root view, while the unbinding method clears the control instance references in the corresponding field when the page or view is destroyed.
[0058] The binding class identifier for the target class is determined based on its fully qualified class name and the module namespace of the project module to which it belongs. The binding class identifier can include the module namespace, the fully qualified class name of the target class, and a preset binding suffix. Using the fully qualified class name of the target class, rather than a simple class name, to generate the binding class identifier further avoids binding class conflicts between target classes with the same name in different package paths within the same project module.
[0059] After generating the compile-time binding class, the fully qualified class name of the target class, the module namespace, the binding class identifier, and the corresponding resource mapping information identifier are associated to generate the module binding index corresponding to the project module to which the target class belongs. The resource mapping information identifier is used to locate the resource mapping information corresponding to the project module to which the target class belongs, and the binding class identifier is used to locate the compile-time binding class corresponding to the target class.
[0060] Module binding indexes can be implemented using generated static index classes, configuration files, service registry, or other structures that can establish a mapping between target classes and bound execution resources. Different project modules generate their own module binding indexes. Component-based binding entry points can be further set up in the application module to aggregate or load the module binding indexes corresponding to each project module as needed.
[0061] In a component-based project, the annotation processing tasks of each project module can run independently and output to their respective generated code directories. The generated compile-time binding classes, resource mapping information, and module binding indexes are all isolated by module namespaces, avoiding annotation processor output conflicts, duplicate binding class names, or resource reference errors between multiple project modules during the compilation phase.
[0062] By generating compile-time binding classes that directly look up and assign control instances during the compilation phase, the field traversal and reflection processing of static layout controls during the page runtime phase can be reduced. By associating the target class, binding class, and resource mapping information with the module binding index, an accurate binding entry point can be provided for the runtime phase, and the efficiency of binding class location and module isolation capability in componentized projects can be improved.
[0063] In one implementation, the hybrid binding engine responds to a control binding request for a target object to be bound, and obtains field binding information pre-associated with the target class based on the type information of the target object. The type information may include the fully qualified class name of the target class to which the target object belongs, and the module namespace of the project module to which it belongs.
[0064] Field binding information includes at least the field identifier, field type, binding type, and control resource information for each field to be bound. Field binding information can be partially derived from the module binding index generated during the compilation phase, and the field binding information corresponding to the runtime binding type can also be obtained by parsing the runtime control binding tags.
[0065] Based on the binding type of each field to be bound, the fields to be bound are divided into a compile-time bound field set and a runtime bound field set. The compile-time bound field set includes fields to be bound that can be found and assigned values through compile-time binding code; the runtime bound field set includes fields to be bound that require querying the control resource ID based on the control resource name and assigning values through reflection.
[0066] For a set of compile-time bound fields, the corresponding compile-time bound class is called based on the association between the target class and the compile-time bound code. The compile-time bound class receives the target object to be bound and the root view, finds the control instance based on the control resource information pre-written in the code, and directly assigns the control instance to the corresponding field to be bound, thus obtaining the compile-time field binding result.
[0067] The compile-time field binding results can include the binding status of each compile-time bound field, the reason for failure, and field information for subsequent unbinding. For successfully bound compile-time bound fields, the corresponding fields can be added to the set of bound fields; for compile-time bound fields that failed to bind, the corresponding failure information can be recorded, and the binding processing of other fields can continue.
[0068] For the set of runtime-bound fields, resource mapping lookup and control instance lookup are performed sequentially to obtain candidate control instances corresponding to each runtime-bound field. After null value and type validation, the candidate control instances are assigned to the corresponding fields to be bound via reflection to obtain the runtime field binding results.
[0069] Compile-time binding and runtime binding can share the target object to be bound, root view, field binding information, and binding result record structure. The two types of binding are scheduled through a unified hybrid binding engine, so that compile-time binding fields and runtime binding fields in the same target class can be processed in the same control binding request, avoiding inconsistencies in state information caused by separate calls to the two binding methods.
[0070] The hybrid binding engine can also determine field binding information based on Android layout type, Android build tool version, control binding tag type, or project module attributes. For example, for control fields in static layouts, compile-time binding types are preferred; for control fields that are dynamically added, loaded conditionally, or whose resource IDs cannot be used as compile-time constants, runtime binding types are used.
[0071] The compile-time field binding results and runtime field binding results are summarized to obtain the control binding results corresponding to the target object. The control binding results can include the set of successfully bound fields, the set of fields that failed to bind, the reason for the failure, and the binding association information required for lifecycle unbinding.
[0072] By processing and unifying compile-time and runtime-bound fields separately, static layout controls can adopt compile-time binding without reflection, while non-final resource IDs or dynamic layout controls retain runtime binding capabilities. This balances the execution efficiency and scenario adaptability of control binding, and ensures that the two binding methods maintain a unified data state and call entry point in the same target class.
[0073] In one implementation, for a set of runtime-bound fields, the control resource name and control resource type corresponding to each field to be bound are obtained sequentially. The control resource name can be provided by the parameters of the runtime control binding tag, and the control resource type can be pre-specified by the control binding tag, or it can be determined by default as an ID type according to the purpose of control binding.
[0074] Obtain the module namespace of the project module to which the target object to be bound belongs. The module namespace can be determined based on the package information of the target class to which the target object to be bound belongs, the module binding index, the module identifier written during the build phase, or the component binding entry point.
[0075] The module namespace, control resource type, and control resource name are combined according to the same combination rules as the resource retrieval identifier to obtain the resource query identifier corresponding to the field to be bound. The composition and order of the resource query identifier are consistent with the resource retrieval identifier used when constructing the resource mapping information to ensure accurate retrieval of the corresponding resource mapping entry.
[0076] The resource query identifier is hashed to obtain the corresponding query hash value. Based on the query hash value, candidate mapping positions in the resource mapping information are determined, and the complete resource retrieval identifiers at these candidate mapping positions are compared. When the complete resource retrieval identifier matches the resource query identifier, the corresponding control resource ID is obtained.
[0077] When no corresponding resource mapping entry is found, the currently unbound field can be marked as having failed to bind, and the module namespace, control resource type, and control resource name can be recorded. A failed resource query only affects the currently unbound field and does not terminate the processing of other runtime binding fields.
[0078] When a control resource ID is retrieved, the corresponding control instance is searched for in the root view based on that ID. The root view can be the top-level view obtained by the Activity through the content view interface, or it can be a view object created by a Fragment. Limiting the control instance search to the root view avoids finding the wrong control instance when there are control resource IDs on different pages or in different Fragments.
[0079] The control instance found based on the control resource ID is used as a candidate control instance. The candidate control instance is not directly assigned to the field to be bound yet, but needs to go through subsequent null value validation, bindable control type validation, and field type matching validation.
[0080] During runtime, the mapping between parsed resource query identifiers and control resource IDs can be cached. When the same target class or the same project module performs binding again, the cached results can be read first. When a change in the project version or resource mapping information is detected, the invalid cache is cleared, thereby ensuring that the cached results are consistent with the current resource mapping information.
[0081] By constructing resource query identifiers based on module namespaces, control resource types, and control resource names, the corresponding control resource IDs can be accurately queried in multi-module projects, avoiding mismatches of resources with the same name across modules; by using hash positioning and control lookup within the root view scope, the efficiency and accuracy of runtime control instance acquisition can be improved.
[0082] In one implementation, null value validation is performed on each candidate control instance. Null value validation is used to determine whether the corresponding control instance can be found in the root view based on the control resource ID. If the candidate control instance is null, it indicates that the corresponding control does not exist in the current layout, the root view is selected incorrectly, or the control resource information does not match the current page. The field to be bound is marked as binding failed, and the reflection assignment process is not entered.
[0083] For candidate control instances whose null value validation result indicates they are not null, determine whether the actual type of the candidate control instance belongs to the preset set of bindable control types. The preset set of bindable control types can include Android native View types and their subclasses, and can also be extended to compatible controls, Material controls, or business-defined controls according to project configuration.
[0084] In one implementation, the preset set of bindable control types can be stored as a whitelist. The whitelist can record the base classes or interfaces of the controls that are allowed to be bound, rather than recording each control implementation class individually. For example, after configuring a View or a preset View subclass as an allowed binding type, the class inheritance relationship can be used to determine whether a candidate control instance belongs to the allowed binding range.
[0085] When a candidate control instance belongs to a predefined set of bindable control types, it is further determined whether the actual type of the candidate control instance and the field type of the field to be bound satisfy an assignable relationship. The type determination interface for the field type can be used to determine whether the field type is a parent class, class class, or compatible interface of the actual type of the candidate control instance. Only when the assignable relationship is satisfied will a type validation result indicating successful validation be obtained.
[0086] For candidate control instances that pass type validation, obtain the field object of the corresponding field to be bound, and enable access permissions for the field to be bound if necessary. Then, use reflection to assign the candidate control instance to the corresponding field to be bound in the target object, obtaining the reflection assignment result.
[0087] The reflection assignment process is set within an independent exception handling scope, with each field to be bound having its own exception handling boundaries. When an illegal access exception, security restriction exception, type conversion exception, or other reflection exception occurs in a field to be bound, the exception corresponding to that field is caught and not further thrown to the upper level of the page.
[0088] For fields that have been successfully assigned values via reflection, a successful binding record is generated. This record can include the identifier of the target object, information about the field to be bound, control resource information, and control instance information. The binding association information between the target object and the control instance is stored as a weak reference. Weak references are used to reduce the risk of the hybrid binding engine holding onto the target object or control instance for an extended period.
[0089] It's important to note that weak references are used to control the reference relationships within the hybrid binding engine, while the field to be bound still retains a field reference to the control instance. Therefore, when the page or view is destroyed, it's necessary to actively clear the control instance references in the field to be bound to complete the full reference release.
[0090] A binding failure record is generated when the candidate control instance is empty, the control instance does not belong to the preset set of bindable control types, the field type does not meet the assignment relationship, or an exception occurs during reflection assignment. The binding failure record may include the name of the field to be bound, the target class name, the module namespace, the control resource name, the control resource ID, and the reason for failure.
[0091] After generating a binding failure record, the binding process for the currently pending field is terminated, and the process continues for the next pending field. The hybrid binding engine can output binding failure records to the logging system, making it easier for developers to locate errors while keeping the overall page running.
[0092] Circuit breaking can also be configured with different levels based on the scope of the exception. Field-level exceptions only terminate the binding of the current field; when the compile-time binding class corresponding to the target class cannot be loaded, the processing of the compile-time binding field set can be terminated, but the processing of the runtime binding field set can continue; when the root view is empty, all binding processing of the current target object to be bound can be terminated and an error result can be returned.
[0093] By performing null value validation, bindable control type validation, and field type matching validation before reflection assignment, illegal binding requests can be intercepted in advance; by adopting field-level exception circuit breaking and logging, the entire page can be prevented from crashing due to the failure of a single control binding; by saving binding association information with weak references and coordinating with lifecycle unbinding, the risk of internal reference residues in the binding engine and page memory leaks can be reduced.
[0094] In one implementation, after the control binding of the target object to be bound is completed, the corresponding lifecycle subject and target destruction event are determined according to the object type of the target object to be bound.
[0095] When the target object to be bound is an Activity object, the lifecycle subject can be the lifecycle management object corresponding to the Activity object, and the target destruction event can be the destruction event of the Activity. When the target object to be bound is a Fragment object, and the field to be bound is used to store control instances in the Fragment view, the lifecycle subject is preferably the lifecycle management object corresponding to the Fragment view, and the target destruction event is preferably the destruction event of the Fragment view.
[0096] By using the lifecycle body corresponding to the Fragment view for listening, the control instance reference can be cleared in time when the Fragment object still exists but its root view has been destroyed, thus avoiding the retention of control references until the Fragment object is finally destroyed.
[0097] Register lifecycle listeners based on the lifecycle subject. Lifecycle listeners can be implemented using the Android Lifecycle Observer interface or registered through the lifecycle callbacks of an Activity or Fragment. Associate the lifecycle listeners with the binding information corresponding to the target object to form a lifecycle binding relationship.
[0098] Lifecycle binding relationships can record the lifecycle subject, the target object to be bound, the set of bound fields, and the target destruction event. For compile-time bound fields, the unbinding method in the corresponding compile-time bound class can be recorded; for runtime bound fields, the field object used to clear the field reference can be recorded.
[0099] The lifecycle listener continuously acquires lifecycle events generated by the lifecycle subject. When the acquired lifecycle event does not match the target destruction event, no unbinding process is performed; when the lifecycle event matches the target destruction event, the set of fields to be unbound is determined based on the lifecycle binding relationship.
[0100] For compile-time bound fields in the set of fields to be unbound, the pre-generated unbinding code in the compile-time binding class can be called to set the corresponding field in the target object to null. For runtime bound fields in the set of fields to be unbound, the corresponding field object can be obtained based on the binding association information, and the control instance reference in the field to be bound can be set to null through field access operations.
[0101] After clearing the control instance references for each field to be bound, delete the binding association information corresponding to each field, and clear the weak references, field metadata, and control binding results stored internally by the hybrid binding engine. Then, unregister the lifecycle listeners to prevent them from continuing to hold the lifecycle subject or the target object to be bound.
[0102] When the same target object is bound to a control multiple times, it's advisable to check if a corresponding binding association already exists before establishing a new lifecycle binding relationship. If it already exists, unbinding or reusing the original lifecycle listener can be performed first to avoid duplicate listener registration.
[0103] By linking control binding relationships with the lifecycle of Activity pages or Fragment views, control instance references and binding association information can be automatically cleared when the corresponding page or view is destroyed. This prevents expired control instances from being continuously held by the target object or binding engine, thereby reducing the risk of memory leaks in Android applications and reducing the maintenance costs of developers manually performing unbinding operations.
[0104] In one implementation, upon receiving a control binding request for a target object, the fully qualified class name of the target object and the module namespace of the project module to which the target object belongs are obtained. The fully qualified class name is used as the target class identifier, and the module namespace is used as the target module identifier.
[0105] The target module identifier can be determined by the building module containing the class corresponding to the target object to be bound, or by the component-based binding entry point based on the correspondence between the target class package path and the module registration information. The target class identifier and the target module identifier are used together to uniquely identify the binding execution resource corresponding to the target object to be bound in the component-based project.
[0106] The module binding index is queried based on the target class identifier and the target module identifier. The module binding index can be obtained by first determining the index range of the corresponding project module based on the target module identifier, and then querying the corresponding binding class identifier and resource mapping information identifier based on the target class identifier.
[0107] The binding class identifier is used to locate and load the compile-time binding class corresponding to the target class. Compile-time binding classes can be obtained through direct instantiation, static registration, or class loading. To reduce the overhead of runtime reflection in finding and generating classes, the module binding indexes of each project module can be registered to the component-based binding entry point during the application initialization phase.
[0108] Resource mapping information identifiers are used to load the resource mapping information of the project module to which the target object to be bound belongs. Resource mapping information can exist in the form of generated classes, binary index files, or module resource configuration objects. After loading, module-level resource mapping information is obtained for runtime resource name lookup.
[0109] The loaded compile-time binding class, resource mapping information, field binding information, and root view are associated to obtain the binding execution information corresponding to the target object to be bound. This binding execution information provides the hybrid binding engine with all the execution data required for the current control binding request.
[0110] The hybrid binding engine calls the compile-time binding class based on the root view and binding execution information to perform direct binding on the compile-time binding field set; at the same time, it processes the fields to be bound of the runtime binding type based on the resource mapping information in the binding execution information to obtain the control binding result corresponding to the target object to be bound.
[0111] When the corresponding binding class identifier does not exist in the module binding index, it can be determined that the current target class does not contain compile-time binding fields, and runtime binding fields can continue to be processed based on resource mapping information. When resource mapping information cannot be loaded, runtime binding processing of the current target class can be stopped, and a module resource loading failure record can be generated without affecting the binding processing of other loaded project modules.
[0112] Each project module maintains its own compile-time binding classes, resource mapping information, and module binding index. The component-based binding entry point only loads the data of the corresponding module as needed based on the target module identifier. Therefore, it is unnecessary to merge the resource mapping information and generated classes from all project modules into a single global structure.
[0113] By jointly querying the module binding index using the target class identifier and the target module identifier, the compile-time binding class and resource mapping information corresponding to the target object to be bound can be accurately loaded in multi-module Android projects, avoiding conflicts between target classes, resources or generated classes with the same name, and reducing the overhead of data loading and cross-module calls in unrelated project modules.
[0114] In one implementation, the Android control hybrid binding system adapted to non-final resource IDs includes a binding information acquisition module, a compilation processing module, a hybrid binding module, a security processing module, and a lifecycle management module. Each module can be implemented by a software program running on a development terminal, build server, or Android terminal, or by a processor executing program instructions stored in memory.
[0115] The binding information acquisition module is used to obtain the resource compilation results of each project module in the target Android project, as well as the control binding tags corresponding to each field to be bound in the target class. The binding information acquisition module may include a resource result acquisition unit and a tag parsing unit.
[0116] The resource result acquisition unit is used to read resource symbol information after resource compilation, obtaining the module namespace, control resource type, control resource name, and control resource ID. The tag parsing unit is used to parse the control binding tags of each field to be bound in the target class, obtaining the field identifier, field type, binding type, and control resource information, and forming field binding information.
[0117] The compilation processing module is used to associate control resource names with control resource IDs according to the module namespace of each project module, generating mutually isolated resource mapping information. The compilation processing module is also used to generate compile-time binding code for fields to be bound for compile-time binding types, and to establish the association between the target class, the compile-time binding code, and the resource mapping information.
[0118] The compilation processing module may include a resource mapping generation unit, an incremental update unit, a binding code generation unit, and an index generation unit. The resource mapping generation unit generates resource retrieval identifiers based on the module namespace, control resource type, and control resource name, and establishes a mapping relationship between the resource retrieval identifiers and control resource IDs using a hash method. The incremental update unit updates changed resource mapping entries based on resource change information.
[0119] The binding code generation unit generates field binding code based on the field identifier, field type, and control resource information of the field to be bound, and generates a compile-time binding class according to the fully qualified class name of the target class and the module namespace. The index generation unit establishes a module binding index between the target class, the compile-time binding class, and the resource mapping information.
[0120] The hybrid binding module is used to respond to control binding requests for the target object to be bound, obtain the root view corresponding to the target object to be bound, and divide the fields to be bound into a set of compile-time bound fields and a set of runtime bound fields according to the field binding information.
[0121] For compile-time bound field sets, the hybrid binding module calls the corresponding compile-time binding class, searches for control instances in the root view, and directly assigns the control instances to the fields to be bound. For runtime bound field sets, the hybrid binding module queries resource mapping information based on the module namespace of the project module to which the target object belongs and the corresponding control resource name to obtain the control resource ID, and then searches for candidate control instances in the root view based on the control resource ID.
[0122] The hybrid binding module can also include a component-based binding entry point. The component-based binding entry point is used to query the module binding index based on the fully qualified class name of the target object to be bound and the module namespace of the project module to which it belongs, and load the corresponding compile-time binding class and resource mapping information to form the binding execution information corresponding to the current target object to be bound.
[0123] The security processing module performs null value validation, bindable control type validation, and field type matching validation on candidate control instances corresponding to the runtime binding type. When the validation passes, the security processing module grants access permissions to the field to be bound and assigns the candidate control instance to the corresponding field to be bound via reflection.
[0124] The security processing module is equipped with a field-level exception circuit breaker mechanism. When an exception occurs during the reflection assignment of a field to be bound, the security processing module terminates the binding process for that field, generates a binding failure record, and continues processing other fields to be bound. For fields that are successfully assigned a value, the security processing module generates a binding success record and saves the corresponding binding association information as a weak reference.
[0125] The lifecycle management module is used to determine the lifecycle subject and target destruction event based on the object type of the target object to be bound, register lifecycle listeners, and establish lifecycle binding relationships between lifecycle listeners and binding association information.
[0126] When the lifecycle management module detects that a page or view has entered a destruction state, it determines the set of fields to be unbound based on the lifecycle binding relationships, clears the control instance references in each bound field, deletes the corresponding binding association information, and unregisters the lifecycle listeners. For Activity objects, unbinding can be performed when the Activity is destroyed; for view fields in Fragment objects, unbinding can be performed when the Fragment view is destroyed.
[0127] The binding information acquisition module and compilation processing module can primarily run during the build phase of the target Android project, while the hybrid binding module, security processing module, and lifecycle management module can primarily run during the runtime phase of the Android application. The resource mapping information, compile-time binding classes, and module binding indexes generated during the build phase serve as inputs for each module during the runtime phase, thus forming a hybrid control binding system that seamlessly integrates the compilation, runtime, and destruction phases.
[0128] Through the above system, each module can work together to process Android non-final resource IDs, control binding, and componentized projects. It completes resource mapping and binding code generation during the build phase, performs hybrid binding, security verification, and circuit breaking during the runtime phase, and releases references during the page or view destruction phase. This improves the compatibility, execution efficiency, stability, and adaptability of the Android control binding process to multi-module projects.
[0129] The technical features of the above embodiments can be combined in any way. For the sake of brevity, not all possible combinations of the technical features in the above embodiments are described. However, as long as there is no contradiction in the combination of these technical features, they should be considered to be within the scope of this specification.
Claims
1. A method for hybrid binding of Android controls that adapts to non-final resource IDs, characterized in that, include: Obtain the resource compilation results of each project module in the target Android project and the control binding mark corresponding to each field to be bound in the target class. Determine the binding type and control resource information of each field to be bound based on the control binding mark. The binding type includes compile-time binding type and runtime binding type. The control resource information corresponding to the runtime binding type includes the control resource name. According to the module namespace of each project module, the control resource name and control resource ID in the resource compilation result are associated, and the isolated resource mapping information corresponding to each project module is generated respectively. The corresponding compile-time binding code is generated for the fields to be bound for the compile-time binding type, and the association relationship between the target class and the corresponding compile-time binding code and resource mapping information is established. In response to a control binding request for a target object to be bound, the root view corresponding to the target object to be bound is obtained, wherein the target object to be bound is an object instance of the target class, and the corresponding control binding process is performed according to the binding type of each field to be bound; For the field to be bound of the compile-time binding type, the corresponding compile-time binding code is called to directly find the corresponding control instance from the root view and assign the control instance to the field to be bound; For the field to be bound in the runtime binding type, the resource mapping information is queried according to the project module to which the target object to be bound belongs and the corresponding control resource name to obtain the corresponding control resource ID, and the corresponding control instance is found from the root view according to the control resource ID; Null value validation and field type matching validation are performed on the control instance found for the runtime binding type. When the validation passes, the control instance is assigned to the corresponding field to be bound via reflection. If the reflection assignment of the current field to be bound fails, the binding process of the current field to be bound is terminated and other fields to be bound are processed. Monitor the lifecycle state of the page or view corresponding to the target object to be bound, and when the page or view enters the destruction state, clear the control instance references in each bound field and release the association information saved during the binding process.
2. The method according to claim 1, characterized in that, The step involves associating the control resource names and control resource IDs in the resource compilation results according to the module namespace of each project module, thereby generating isolated resource mapping information corresponding to each project module, including: After the resources of the target Android project are compiled, the resource symbol information corresponding to each project module is parsed to obtain the module namespace, control resource type, control resource name and control resource ID corresponding to each control resource; The module namespace, control resource type, and control resource name corresponding to each control resource are combined to obtain the resource retrieval identifier corresponding to each control resource; Hash each resource retrieval identifier to obtain the corresponding mapping storage location; According to each mapping storage location, each resource retrieval identifier is associated with the corresponding control resource ID and stored to obtain the resource mapping information corresponding to each project module, so that control resources with the same control resource name in different project modules correspond to different resource retrieval identifiers.
3. The method according to claim 2, characterized in that, Also includes: Obtain the resource change information of the target Android project, and determine the target control resources that have been added, modified or deleted based on the resource change information to obtain the resource change set; Based on the module namespace corresponding to each target control resource in the resource change set, determine the resource mapping entries to be updated from the resource mapping information corresponding to each project module; Based on the change type corresponding to each target control resource, perform add, replace, or delete operations on the resource mapping entries to be updated to obtain the updated resource mapping entries; The updated resource mapping entries are written into the resource mapping information of the corresponding project module to obtain the incrementally updated resource mapping information.
4. The method according to claim 1, characterized in that, The process of generating corresponding compile-time binding code for the fields to be bound of the compile-time binding type, and establishing the association between the target class and the corresponding compile-time binding code and resource mapping information, includes: Parse the control binding tag corresponding to the compile-time binding type to obtain the field identifier, field type, and control resource information of the corresponding field to be bound; Based on the field identifier, the field type, and the control resource information, generate field binding code for finding control instances from the root view and assigning the control instances to the field to be bound; Based on the fully qualified class name of the target class and the module namespace of the project module to which the target class belongs, determine the binding class identifier corresponding to the target class, and generate the compile-time binding class corresponding to the target class based on the field binding code corresponding to each field to be bound; Associating the fully qualified class name of the target class, the module namespace, the binding class identifier, and the corresponding resource mapping information identifier generates a module binding index corresponding to the project module to which the target class belongs.
5. The method according to claim 1, characterized in that, The step of performing corresponding control binding processing based on the binding type of each field to be bound includes: Based on the type information of the target object to be bound, obtain the field binding information that is pre-associated with the target class. The field binding information includes the binding type and control resource information of each field to be bound. Based on the binding type of each field to be bound, the fields to be bound are divided into a set of compile-time bound fields and a set of runtime bound fields; The corresponding compile-time binding code is invoked for the aforementioned compile-time bound field set to obtain the compile-time field binding results; Perform resource mapping query and control instance lookup on the set of runtime binding fields to obtain candidate control instances corresponding to each runtime binding field; Runtime field assignment is performed based on the candidate control instance to obtain the runtime field binding result. The compile-time field binding result and the runtime field binding result are then combined to obtain the control binding result corresponding to the target object to be bound.
6. The method according to claim 5, characterized in that, The process of performing resource mapping queries and control instance searches on the set of runtime binding fields to obtain candidate control instances corresponding to each runtime binding field includes: Sequentially obtain the control resource name and control resource type corresponding to each field to be bound in the runtime binding field set, and obtain the module namespace of the project module to which the target object to be bound belongs; The module namespace, the control resource type, and the control resource name are combined to obtain the resource query identifier corresponding to each field to be bound; The resource query identifier is used to query the resource mapping information of the corresponding project module to obtain the control resource ID corresponding to each field to be bound; Based on the resource ID of each control, the corresponding control instance is found in the root view to obtain the candidate control instance corresponding to each field to be bound.
7. The method according to claim 6, characterized in that, The step of performing runtime field assignment processing based on the candidate control instance to obtain the runtime field binding result includes: Determine whether each candidate control instance is empty, and obtain the null value verification result for each candidate control instance; For candidate control instances whose null value validation result indicates that they are not null, determine whether the actual type of the candidate control instance belongs to the preset set of bindable control types, and determine whether the actual type of the candidate control instance and the field type of the corresponding field to be bound satisfy the assignable relationship, and obtain the type validation result; For candidate control instances whose type validation results indicate that the validation has passed, access permissions are granted to the corresponding fields to be bound, and the candidate control instances are assigned to the corresponding fields to be bound via reflection to obtain the reflection assignment result. For the field to be bound that indicates a successful assignment result from the reflection assignment, the binding association information between the target object to be bound, the field to be bound, and the corresponding control instance is saved in the form of a weak reference to obtain a successful binding record; For fields to be bound that are empty, fail type validation, or have an error during reflection assignment, a binding failure record containing information about the field to be bound, control resource information, and the reason for failure is generated. The binding process of the current field to be bound is terminated, and the next field to be bound is processed to obtain the runtime field binding result.
8. The method according to claim 7, characterized in that, The monitoring of the lifecycle state of the page or view corresponding to the target object to be bound, and the clearing of control instance references in each bound field and the release of association information saved during the binding process when the page or view enters the destruction state, includes: Based on the object type of the target object to be bound, determine the lifecycle subject and target destruction event corresponding to the target object to be bound. The lifecycle subject includes the lifecycle subject corresponding to the Activity object or the lifecycle subject corresponding to the Fragment view. Register a lifecycle listener based on the lifecycle subject, and associate the lifecycle listener with the binding association information to obtain the lifecycle binding relationship; The lifecycle listener acquires lifecycle events generated by the lifecycle subject, and when the lifecycle event matches the target destruction event, the set of fields to be unbound is determined according to the lifecycle binding relationship. The target object to be bound is obtained based on the binding association information, and the control instance references of each field to be bound in the set of fields to be unbound are cleared. The binding association information corresponding to each field to be bound is deleted, and the unbinding result corresponding to the target object to be bound is obtained.
9. The method according to claim 4, characterized in that, In response to a control binding request for a target object to be bound, the root view corresponding to the target object to be bound is obtained, and corresponding control binding processing is performed according to the binding type of each field to be bound, including: Obtain the fully qualified class name of the target object to be bound and the module namespace of the project module to which the target object to be bound belongs, and obtain the target class identifier and the target module identifier; Based on the target class identifier and the target module identifier, the module binding index is queried to obtain the binding class identifier and resource mapping information identifier corresponding to the target object to be bound; Load the corresponding compile-time binding class according to the binding class identifier, and load the resource mapping information of the corresponding project module according to the resource mapping information identifier, to obtain the binding execution information corresponding to the target object to be bound; The compile-time binding class is invoked based on the root view and the binding execution information, and the unbound fields of the runtime binding type are processed using the resource mapping information to obtain the control binding result corresponding to the unbound target object.
10. An Android control hybrid binding system that adapts to non-final resource IDs, characterized in that, include: The binding information acquisition module is used to acquire the resource compilation results of each project module in the target Android project and the control binding mark corresponding to each field to be bound in the target class. Based on the control binding mark, the binding type and control resource information of each field to be bound are determined. The binding type includes compile-time binding type and runtime binding type. The control resource information corresponding to the runtime binding type includes the control resource name. The compilation processing module is used to associate the control resource name and control resource ID in the resource compilation result according to the module namespace of each project module, generate mutually isolated resource mapping information corresponding to each project module, generate corresponding compile-time binding code for the fields to be bound for the compile-time binding type, and establish the association relationship between the target class and the corresponding compile-time binding code and resource mapping information. The hybrid binding module is used to respond to control binding requests for target objects to be bound, obtain the root view corresponding to the target object to be bound (the target object is an object instance of the target class), and perform corresponding control binding processing according to the binding type of each field to be bound. For fields to be bound of the compile-time binding type, the corresponding compile-time binding code is called to directly find the corresponding control instance from the root view and assign the control instance to the field to be bound. For fields to be bound of the runtime binding type, the resource mapping information is queried according to the project module to which the target object to be bound belongs and the corresponding control resource name to obtain the corresponding control resource ID, and the corresponding control instance is found from the root view according to the control resource ID. The security processing module is used to perform null value validation and field type matching validation on the control instance found for the runtime binding type. When the validation passes, the control instance is assigned to the corresponding field to be bound via reflection. When the reflection assignment of the current field to be bound fails, the binding process of the current field to be bound is terminated and other fields to be bound are processed. The lifecycle management module is used to monitor the lifecycle status of the page or view corresponding to the target object to be bound, and when the page or view enters the destruction state, it clears the control instance references in each bound field and releases the association information saved during the binding process.
