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

  1. The so library referenced in the project is all about when the functionality will be loaded again
  2. The loading timing of the SO library introduced by the third-party JAR (AAR) is not controlled by our code logic
  3. Use so libraries that are suitable for asynchronous loading
  4. So library files are not downloaded before the user with related functions how to deal with
  5. Version iteration so file upgrade how to handle
  6. 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