function

  • Use Xpose means to integrate Bugly, Httploggingtor and other tripartite libraries for APP.

Steps (using integrating HttpLoggingInterceptor as an example)

Step 1 Download the DEX file to the mobile phone

You can download the JAR package from the Httploggingtor interceptor and use the script in the dex-jar tool to convert the JAR package into a dex file and save it to your mobile phone.

Step 2 Build a DexClassLoader

    // HTTP log dex path
    private val dexPath = "/ storage/emulated / 0 / Download/logging - interceptor - 3.12.10 - jar2dex. Dex." "

    private val dexClsLoader by lazy {
        / / define DexClassLoader
        // The first argument is the path to the dex compressed file
        // The second parameter is the directory where dex is stored after decompression
        // The third argument: is the C/C++ dependent local library directory, can be null
        // The fourth argument is the upper-level class loader

        valdexOutputDir = appContext? .getDir("dex".0)? .absolutePath ? :null
        DexClassLoader(dexPath, dexOutputDir, null, clsLoader)
    }
Copy the code

Step three: Get two dexElements arrays

Through reflection, obtain the pathList in DexClassLoader, and then obtain the dexElements in pathList. Similarly, get the dexElements of the system classLoader

public class BaseDexClassLoader extends ClassLoader {
    private final DexPathList pathList;
}


final class DexPathList {
    private Element[] dexElements;  // This is what we need
}
Copy the code

Step 4 Merge the two dexElements arrays

        / / DexElements merge
        val combined = java.lang.reflect.Array.newInstance(classLoaderElements.javaClass.componentType,
                classLoaderElements.size + myDexClassLoaderElements.size) as Array<Any>
        System.arraycopy(classLoaderElements, 0, combined, 0, classLoaderElements.size)
        System.arraycopy(myDexClassLoaderElements, 0, combined, classLoaderElements.size, myDexClassLoaderElements.size)

        // Finally replace 'dexElements' in system' ClassLoader 'with reflection
Copy the code

Step 5 Perform HttpLogginInterceptor initialization

hookFun("okhttp3.OkHttpClient.Builder", clsLoader, "build".object: MethodHookCallback() {
    override fun before(param: MethodHookParam) {
        valbuilder = param.thisObject? :return
        (builder["interceptors"] as? ArrayList<*>)? .takeIf { it.isNotEmpty() }? :return
        vallogging = httpLoggingInterceptorCls? .newInstance()? :return
        val levelBasic = "okhttp3.logging.HttpLoggingInterceptor\$Level".toClass(clsLoader)["HEADERS"]? :return
        logging.call("setLevel", levelBasic)
        builder.call("addInterceptor", logging)
        logD("We're done.")}override fun after(param: MethodHookParam){}})Copy the code

conclusion

  1. code