I. BACKGROUND
In the development of the implementation of the Android application, sometimes need to introduce a third-party so Lib library, but the third party so cubby large, such as open source Third-party playback Component FFmpeg Library, if directly packaged in the APK package inside, The entire application would be a lot bigger. After consulting the data and experiments, it is found that it is feasible to download so files remotely and then register the so file dynamically. The main need to solve the download so file storage location and file read and write permission issues.
second, the main ideas
1, first put so on the network above, such as Test put to: http://codestudy.sinaapp.com//lib/test.so
2, the application starts, the asynchronous thread to download the so file, and write to the/data/data/packagename/app_libs directory below
3, call System.load registration so file. Because the path must have execute permission, we cannot load so on the SD card, but we can write the so file to the application's private directory by calling Context.getdir ("Libs", Context.mode_private)/data/data/ Packagename/app_libs.
third, code implementation
1, the network download so file, and write to the application of the private directory/data/data/packagename/app_libs
The code is as follows |
Copy Code |
/** * Download files to/data/data/packagename/app_libs below * @param context * @param URL * @param fileName * @return */ public static File Downloadhttpfiletolib (context, string URL, string fileName) { Long start = System.currenttimemillis (); FileOutputStream outstream = null; InputStream is = null; File sofile = null; try { HttpClient client = new Defaulthttpclient (); HttpGet get = new HttpGet (URL); HttpResponse response = Client.execute (get); httpentity entity = response.getentity (); File dir = context.getdir ("Libs", context.mode_private); Sofile = new File (dir, fileName); OutStream = new FileOutputStream (sofile); is = Entity.getcontent (); if (is!= null) { byte[] buf = new byte[1024]; int ch =-1; while (ch = is.read (buf)) > 0) { Outstream.write (buf, 0, ch); LOG.D (">>>httpdownloadfile:", "Download in progress ..."); } } Outstream.flush (); Long end = System.currenttimemillis (); LOG.D (">>>httpdownloadfile Cost Time:", (End-start)/1000 + "s"); LOG.D (">>>httpdownloadfile:", "download Success"); return sofile; catch (IOException e) { LOG.D (">>>httpdownloadfile:", "Download Failed" + e.tostring ()); return null; finally { if (OutStream!= null) { try { Outstream.close (); catch (IOException e) { E.printstacktrace (); } } if (is!= null) { try { Is.close (); catch (IOException e) { E.printstacktrace (); } } } } |
2, call System.load registration so file
The code is as follows |
Copy Code |
New Thread (New Runnable () { @Override public void Run () { File sofile = Fileutils.downloadhttpfiletolib (Getapplicationcontext (), "http://codestudy.sinaapp.com//lib/test.so" , "test.so"); if (sofile!= null) { try { LOG.D (">>>loadappfile Load Path:", Sofile.getabsolutepath ()); System.load (Sofile.getabsolutepath ()); catch (Exception e) { LOG.E (">>>loadappfile Load Error:", "So load failed:" + e.tostring ()); } } } ). Start (); |
Iv. issues to be addressed
1, so file download and registration opportunity. Test found libffmpeg.so 8M file single-threaded download requires 10-13s around
2, so download failure or registration failure how to deal with. For example, so play components try to use the Android system native MediaPlayer for playback
3, when the first so has not downloaded a successful registration, enter the playback page, you need to be friendly to prompt users, such as loading video is loading and so on
4, no network situation, etc.
v. Description
The above demo after 3 (2.3/4.2/4.4) actual model test can be used normally, and then according to the 4th list of problems to improve the following, you can use.