The background that
In the process of business development, we often enter some third-party SDKS, which introduce SO library. Some SO library files are relatively large. At this time, we need to consider that so library can be loaded asynchronously from the network to reduce the volume of the release package
Traditional scheme
The core idea of so library file into the network -> download to the local sandbox -> through the System. Load seems quite simple, however, a lot of information did not mention is
So inventory is dependent on relationships
For example, when you put libunity. So download through the System. The load (“/data/data/com. Example. Soload/files/libunity. So “) will get the following abnormal loading
java.lang.UnsatisfiedLinkError: dlopen failed: Library “libmain. So” not found at Java lang. Runtime. LoadLibrary0 ats (Runtime. Java: 1071) java.lang.Runtime.loadLibrary0(Runtime.java:1007) at java.lang.System.loadLibrary(System.java:1667)
Cause analysis,
The solution
Before loading libuny. so, you need to load libmain.so
Expand the thinking
How do we control the loading order when we write the code github.com/facebook/S…. Github.com/KeepSafe/R…. The core idea of the above two open source libraries is to parse the so library ELF format, analyze the dependencies and recurse, until the dependencies are loaded and then loaded itself here does not extend to interested partners can look at the source code
The text relocations problem
When you download liblbs.so down through
System. The load (“/data/data/com. Example. Soload/files/liblbs. So “) and surprises when the Java. Lang. UnsatisfiedLinkError: dlopen failed: “/ data/data/com. Example. Soload/files/liblbs. So” from the text relocations (android. Googlesource…). at java.lang.Runtime.load0(Runtime.java:938) at java.lang.System.load(System.java:1631)==
Cause analysis:
blog.csdn.net/chjqxxx…
Expand your thinking:
We can do a self-check by command
If you have the source code, you can recompile it. If you don’t have the source code, you can lower targetSdkVersion.
Advanced solutions
Are there any other solutions besides system.load? The answer is yes github.com/Tencent/ti. Insert custom native path into nativeLibraryDirect ories via reflection. Also give priority to the specified path outside so interception here tinker code com. Tencent. Tinker. Lib. If TinkerLoadLibrary. Java
Does this solution look simpler? Since this solution is an unconventional method and has compatibility risks, we need to verify the compatibility of this solution, write a HelloWord SO, load it through this solution, find a version line in advance and take it up for buried point statistics, so far the latest version has been online for 2 days, and the statistics are as follows
Among them, 1 case of failure was caused by deliberate verification failure in self-test before launching. That is to say, it can be considered that the reform scheme is reliable so far. Of course, we still need to pay attention to the compatibility of the new version if there is a new version update of Android system in the future
The project application
So much has been laid down above, it is one thing to get into the technical scheme, it is another thing to implement the actual project. Now let’s start thinking about the following questions
- The so library referenced in the project is all about when the functionality will be loaded again
- The loading timing of the SO library introduced by the third-party JAR (AAR) is not controlled by our code logic
- Use so libraries that are suitable for asynchronous loading
- So library files are not downloaded before the user with related functions how to deal with
- Version iteration so file upgrade how to handle
- How to eliminate the SO file in the packaging stage
Solve problems 1, 2 and 3
We can solve this problem by using the open source library github.com/HujiangTec…. Since the loading of so library is carried out by calling the System function system.loadLibrary, we can intercept the call of this function globally and print the call chain, run the APP and cooperate with the log to analyze the specific use of so library
Here we need to analyze according to our own business scenarios. For example, asynchronous loading is not recommended for libraries that rely on the home page of the APP. Libraries that need asynchronous loading had better complete a function (we need to group them logically according to experience and refer to the figure at the beginning of the article).
Solve problems 4 and 5
Android uses the Activity as a unit of Activity, and starts the Activity with the startActivity function call, so we can intercept our own logic
The general idea is as follows
Corresponding implementation of part of the code screenshot
Through the logic of rule configuration + bytecode interception, dynamic loading can be realized without invading the original business. Research and development focus on normal business logic, there is no need to write specific codes to introduce new SO library later, modify the configuration file. In the process of implementation, some details need to be considered For example, check the integrity of downloaded files, should download support resumable breakpoints,so files need to update how to deal with
Problem solving 6
Through the above introduction, we have implemented the asynchronous loading of so files
But when packaging, how can we eliminate so and reduce the size of the final release package
This can be configured in build.gradle
But as mentioned above, we configure the rules through JSON
Do this again
It is also possible that the two configurations are inconsistent
And our big rule is decoupling
So let’s continue the hook packaging process
Summary summary
Through the above introduction, the principle is roughly explained
Interested partners can comment on the comments section, put forward their own ideas
At present, it is still in the gray level verification stage, and the relevant code will be released in the comment area after the online verification is stable
So asynchronous loading scheme is much the same, compared with other schemes
The personal feeling characteristic is low invasiveness
Access takes only three steps
To be continued
At present, there are still several points to be optimized
= = = = = = = = = = = = = = = = = = = =
Question 1
The ideal way to load the so library is that both the traditional solution and the advanced solution should be supported. In the beginning, I actually wanted to use the traditional solution to implement it, but the solution has a problem in Unity (Unity related so loading logic is a bit special there is a case of loading so directly through JNI because there is no source code The internal logic is not clear.) It needs further study and improvement after all, the official system. load API provided by the official System is more reliable
Question 2
The progressive-loaded dialog is attached to the window that called startActivity. If finish is called immediately after startActivuty, the Dialog will leak This can be done by starting an activity agent of type FLAG_ACTIVITY_NEW_TASK, but it feels a bit heavy and is still a bit of a struggle
Question 3
At present, the files are only put into Ali Cloud. Users’ network environment is complex and changeable, so they need to consider supporting Tencent Cloud, Qiuniuyun and other more service providers.
Question 4
Uploading to OSS is currently done manually and requires scripting.
The front end