Android dynamically loads so files

Calling dynamic library files (*.so) in Android is done through jni, and often when calling so files in apk or jar packages, the corresponding so files must be packaged into apk or jar packages. The project directory is as follows:

Problems with the above methods:

  1. The lack of flexibility is similar to static loading (not static loading), and the so files that can be loaded are bound dead;

  2. However, when there are many or large so files, the corresponding apk and jar packages will be large;

  3. The so file cannot be updated dynamically;

 

The provided API for loading so files in Android:

void System.load(String pathName);

 

illustrate:

  1. pathName: file name + file path;

  2. After the method is called successfully, the exported functions in the so file will be inserted into a mapping table (type Map) provided by the system;

 

Seeing the function description for System.load(String pathName); above, it is certain that someone will think of putting the so file in a specified directory and then directly referencing the path of the directory and the corresponding so file through the parameter pathName. The problem will not be solved. Yet?

There is a problem that has been ignored here, that is, System.load can only load so files in two directories:

  1、/system/lib ;

  2. The way to install the package, namely: /data/data/<packagename>/…

Moreover, these two road strengths are protected by permission and cannot be accessed directly;

 

Problem solution:

First download the so file from the network to the mobile phone directory (eg: /test/device/test.so) -> load test.so into the memory (ByteArrayOutputStream) -> then save it to the corresponding installation package directory;

The specific code is as follows:

复制代码
try { 
            String localPath = Environment.getExternalStorageDirectory() + path; 
            Log.v(TAG, "LazyBandingLib localPath:" + localPath); 

            String[] tokens = mPatterns.split(path); 
            if (null == tokens || tokens.length <= 0 
                    || tokens[tokens.length - 1] == "") { 
                Log.v(TAG, "非法的文件路径!"); 
                return -3; 
            } 
            // 开辟一个输入流 
            File inFile = new File(localPath); 
            // 判断需加载的文件是否存在 
            if (!inFile.exists()) { 
                // 下载远程驱动文件 
                Log.v(TAG, inFile.getAbsolutePath() + " is not fond!"); 
                return 1; 
            } 
            FileInputStream fis = new FileInputStream(inFile); 

            File dir = context.getDir("libs", Context.MODE_PRIVATE); 
            // 获取驱动文件输出流 
            File soFile = new File(dir, tokens[tokens.length - 1]); 
            if (!soFile.exists()) { 
                Log.v(TAG, "### " + soFile.getAbsolutePath() + " is not exists"); 
                FileOutputStream fos = new FileOutputStream(soFile); 
                Log.v(TAG, "FileOutputStream:" + fos.toString() + ",tokens:" 
                        + tokens[tokens.length - 1]); 

                // 字节数组输出流,写入到内存中(ram) 
                ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
                byte[] buffer = new byte[1024]; 
                int len = -1; 
                while ((len = fis.read(buffer)) != -1) { 
                    baos.write(buffer, 0, len); 
                } 
                // 从内存到写入到具体文件 
                fos.write(baos.toByteArray()); 
                // 关闭文件流 
                baos.close(); 
                fos.close(); 
            } 
            fis.close(); 
            Log.v(TAG, "### System.load start"); 
            // 加载外设驱动 
            System.load(soFile.getAbsolutePath()); 
            Log.v(TAG, "### System.load End"); 

            return 0; 

        } catch (Exception e) { 
            Log.v(TAG, "Exception   " + e.getMessage()); 
            e.printStackTrace(); 
            return -1; 

}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326844032&siteId=291194637