Author: Uproot

Youku App is connected to the Small program framework of Alipay, which expands the capabilities of Youku App. However, due to the difference in the running environment of Youku App and Alipay App platform during the built-in small program SDK, the following major problems arise:

  • The small program SDK package is large, which greatly increases the package size of Youku APP.
  • After the startup of the small program container, the number of threads increased dramatically, and the scene threads of Youku main APP were superimposed, resulting in an increase in crash rate.
  • Initializing the applets engine will affect the startup speed and memory usage of Youku APP.

In order to solve the above problems, Youku is bound to have different processing in package size, thread number, memory and other aspects. Next, this article will introduce youku’s solutions when facing these differences and problems.

Remote, SO

During the built-in process, we found that the Alipay applet framework took up about 23MB. The ideal solution is all remoteness, which does not occupy the package size of Youku App. However, youku does not have the conditions for all remoteness in a short period of time. Through analysis, we found that SO accounted for 7MB of 23MB space, and SO was relatively independent compared to code and resource files. Therefore, our plan is as follows:

  • There are dependencies between so, which need to be collected in advance and loaded in sequence when loading;
  • These SOS are excluded in the packaging process, uploaded to the server, and the relevant information of SO is recorded. It includes the remote download address and MD5 value.
  • When the user opens the APP and enters the small program, the so is downloaded from the server and stored in the specified directory.
  • Load so in sequence according to the pre-collected dependencies.

Among them, so dependency analysis is more complex, and our processing process is as follows:

1. Analyze dependencies

objdump -x *.so|grep -i needed|awk '{print $2}'
Copy the code

Objdump is a Linux disassembly of object files or executables in a readable format that tells you more about the additional information that binaries may have, as well as the readelf command. Depending on SO, some of them belong to the operating system, and some belong to other AAR packages. There is no need to care about the operating system, and the SO in other AAR packages need to be recorded.

2. Collect dependencies:

Aar package name SO the name Dependent SO name Effective depends on
com.AAA:aaa-build libA1.so libopenssl.so libandroid.so liblog.so libm.so libstdc++.so libEGL.so libGLESv2.so libOpenSLES.so libz.so libdl.so libc.so libopenssl.so
libA2.so libB1.so liblog.so libandroid.so libstdc++.so libm.so libc.so libdl.so libB1.so
com.BBB:bbb-build libB1.so libopenssl.so libc++_shared.so liblog.so libz.so libc.so libm.so libdl.so

You can refer to the above table to collect the dependency information of each SO, and finally these SO relationships can form a network. As follows:

3. Hierarchical dependencies:

The design principles for hierarchical dependencies are as follows:

  • Layer 1: It is not allowed to rely on the SO in any other AAR package, only the SO that depends on the operating system or the SO that has no dependency;
  • Layer 2: Only SOS that rely on layer 1 collections and the operating system are allowed;
  • Layer 3: Only SOS collected by layer 1 and Layer 2 and the OPERATING system are allowed.

And so on.

Layer 1 (XX) Layer 2 (XX) Layer 3 (XX) The fourth floor (XX) Fifth Floor (XX)
A1 B1 C1
A2 B2 C2
A3 B3
A4

4. Code implementation

Private static String[] LIB_NAMES = {private static String[] LIB_NAMES = {private static String[] LIB_NAMES = {so "A1", "A2", "A3", "A4", // "C1", "C2", "C1", "C2"; // The first four stages are loaded... }; public static void ensureAllSoLoaded() { try { for (String lib_name : LIB_NAMES) { Log.d(TAG, "lib_name:" + lib_name); System.loadLibrary(lib_name); } } catch (Throwable throwable) { Log.e(TAG, "loadLibrary lib_name exception:"); throwable.printStackTrace(); }}Copy the code

5, summary

In the process of integrating applets, Youku reduced the package size of 7MB by remote so. Accordingly, when the user enters the small program for the first time, it needs a certain waiting time, which affects the user experience a little.

Injecting a thread pool

In some mobile phones, especially Huawei phones, there is an upper limit for the number of APP threads, exceeding which will crash. Based on this, Youku APP controls threads through a unified thread pool. When the number of threads reaches a certain number, tasks will be executed through queuing instead of adding new threads.

Due to different business attributes, the number of threads starting the page of Youku Player is very large. Once entering the page during use, the number of threads can reach up to 300+. The page if there is a small program entrance, once you start the small program, the number of threads will increase about 100 on the original basis. So it is easy to achieve APP upper limit of the number of threads, lead to Java. Lang. An OutOfMemoryError.

In fact, through online monitoring platform, it is found that there are quite a few crashes caused by this reason. So, how to solve this problem?

A better solution is to integrate the threads of Alipay small program framework into the unified thread pool of Youku for management. In this way, when the Alipay applets framework wants to execute a task, it only needs to submit the task to the Youku thread pool for execution, without actually creating the thread. Youku thread pool determines whether to create new threads or queue execution according to the system situation.

Through communication with colleagues in Alipay, they also agree with this plan. The interface is provided by alipay applets framework to inject youku unified thread pool into applets framework. When the bottom judgment has youku unified thread pool, directly use, no new.

The implementation is as follows:

public class MyThreadPoolManager implements IThreadPoolManager { private static final int NCPU = Runtime.getRuntime().availableProcessors(); private ThreadPoolExecutor mThreadPoolExecutor; @Override public ThreadPoolExecutor createExecutor(ScheduleType scheduleType) { if (mThreadPoolExecutor == null) { mThreadPoolExecutor = YKExecutorService.from("miniappSdk", 2 * NCPU + 1, 2 * NCPU + 1 ,1000, TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>()); } return mThreadPoolExecutor; // Alipay applet framework provides interface to inject youku thread pool. TinySdk.setThreadPoolManager(new MyThreadPoolManager())Copy the code

Before and after the launch, it can be seen from the following data that the effect is very significant. Almost every module has 90% less crash. The data comparison results are as follows:

Lazy loading

At the initial stage of the launch of small program, the business volume is not large. If youku APP initializes the small program framework immediately upon startup, the startup speed will be affected and the memory will be wasted. So our strategy is lazy loading. The process is as follows:

1. Remote dependency check

Applets run with remote dependencies that require traffic and wait time to download. Therefore, when we open the small program business for the first time, the popup window will tell the user these information and ask whether they agree with it. If the user does not accept, the popup window will be closed and the user will not enter the small program APP. If the user accepts, the remote dependency is downloaded and the subsequent process is automatically completed once the download is complete.

2. Check the running conditions of small programs

It is the rendering kernel that finally loads the page of the applet. When the running condition check finds that the running condition is not met, that is, when the applet is cold started, it must judge whether the rendering kernel has been loaded (note: the rendering kernel is not only dependent on the applet, but may be loaded by other services first).

With the rendering kernel initialized, we continue with the initialization of the applets framework. Wait until the normal end of this step, small program operation conditions are fully equipped. We can load the applet page normally.

After initialization, the variable indicates that not all memory is reclaimed when the applets exit. So the second and subsequent hot load applets. The rendering kernel initialization and applets framework initialization are also much faster.

Summary and Outlook

Youku APP mainly provides content services for users. After integrating the small program framework of Alipay, it expands the scope of content services and further expands the capability of Youku as a platform. Youku will continue to make efforts in the following technical directions:

  1. Package the overall small program framework into the cloud, completely eliminate the impact of integrated small program framework on the size of Youku APP package.
  2. Add more general JSAPI to make business side use more convenient.
  3. Loading at leisure replaces lazy loading, providing better business experience and forming positive feedback.

Follow us every week for 3 mobile technology practices & dry goods for you to think about!