{"id":354,"date":"2014-03-30T13:18:20","date_gmt":"2014-03-30T11:18:20","guid":{"rendered":"http:\/\/www.nuage.ch\/site\/?p=354"},"modified":"2014-03-30T13:19:23","modified_gmt":"2014-03-30T11:19:23","slug":"android-jni-problem-with-libraries","status":"publish","type":"post","link":"https:\/\/nuage.ch\/site\/android-jni-problem-with-libraries\/","title":{"rendered":"Android JNI, problem with libraries"},"content":{"rendered":"<p>The goal of this article is to explain how to support &#8220;shorcuts&#8221; in libraries on Android.<\/p>\n<p>On Linux you have this type of structure<br \/>\n* \/lib\/x86_64-linux-gnu\/libusb-1.0.so -> Link to libusb-1.0.so.0<br \/>\n* \/lib\/x86_64-linux-gnu\/libusb-1.0.so.0 -> Link to libusb-1.0.so.0.1.0<br \/>\n* \/lib\/x86_64-linux-gnu\/libusb-1.0.so.0.1.0<\/p>\n<p>I need to support some libraries using this naming convention: x.so.4, where you have the version of the library at the end of the library. When you have multiple libraries and call between the different libraries, you need to be able to support *.so.version.<\/p>\n<p>The problem with android is that you can only deploy a library like {something}.so. You cannot deploy {something}.so.version<\/p>\n<p>As an example liba.so.4, need access to libb.so.5. If you only have liba.so and libb.so, you cannot find libb.so.5.<\/p>\n<p>The secret is to create a symlink on deployement.<\/p>\n<p><strong>Phase 1<\/strong><\/p>\n<p>Add to your project the libs you want to support. Just install the *.so file: Example: libusb-0.1.so. Take care of copying the real version of the lib in your project, not the shortcut.<\/p>\n<p>As an example, if you only support &#8220;armabi&#8221;, you can copy them into \/libs\/armeabi\/<\/p>\n<p><strong>Phase 2<\/strong><\/p>\n<p>Create a static enumeration of the libraries<\/p>\n<p><code>private static String LIBS[] = new String[] { \"libusb-0.1.so.4\",<br \/>\n\t\t\t\"libiconv.so.2\", ...};<br \/>\n<\/code><\/p>\n<p><strong>Phase 3<\/strong><\/p>\n<p>Create the symlinks and Load the libraries <\/p>\n<p><code><\/p>\n<p>\tprivate static boolean isLibInit = false;<\/p>\n<p>\tprivate void initLib(Activity activity) throws IOException {<\/p>\n<p>\t\tif (isLibInit) {<br \/>\n\t\t\treturn;<br \/>\n\t\t}<\/p>\n<p>\t\tFile pathLib = new File(activity.getApplicationInfo().nativeLibraryDir);<br \/>\n\t\tFile pathDest = new File(activity.getFilesDir(), \"lnlib\");<br \/>\n\t\tpathDest.mkdirs();<\/p>\n<p>\t\t\/\/ We only have the \".so\" libs => we need to create a symlink to the<br \/>\n\t\t\/\/ .so.3, .so.1 name!<br \/>\n\t\t\/\/ It's what this loop does!<br \/>\n\t\t{<\/p>\n<p>\t\t\tfor (String f : LIBS) {<br \/>\n\t\t\t\tint p = f.lastIndexOf(\".so.\");<br \/>\n\t\t\t\tif (p >= 0) {<\/p>\n<p>\t\t\t\t\tString orf = f.substring(0, p + 3);<\/p>\n<p>\t\t\t\t\tFile src = new File(pathLib, orf);<br \/>\n\t\t\t\t\tFile dest = new File(pathDest, f);<\/p>\n<p>\t\t\t\t\tif (!dest.exists()) {<br \/>\n\t\t\t\t\t\tProcess proc = Runtime.getRuntime().exec(<br \/>\n\t\t\t\t\t\t\t\tnew String[] { \"ln\", \"-s\",<br \/>\n\t\t\t\t\t\t\t\t\t\tsrc.getAbsolutePath(),<br \/>\n\t\t\t\t\t\t\t\t\t\tdest.getAbsolutePath() });<br \/>\n\t\t\t\t\t\ttry {<br \/>\n\t\t\t\t\t\t\tproc.waitFor();<br \/>\n\t\t\t\t\t\t} catch (Throwable t) {<br \/>\n\t\t\t\t\t\t\tt.printStackTrace();<br \/>\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t}<\/p>\n<p>\t\t\t\t}<br \/>\n\t\t\t}<\/p>\n<p>\t\t}<\/p>\n<p>\t\t\/\/ Load libs<br \/>\n\t\tfor (String f : LIBS) {<br \/>\n\t\t\tFile dest = new File(pathDest, f);<br \/>\n\t\t\tSystem.load(dest.getAbsolutePath());<br \/>\n\t\t}<\/p>\n<p>\t\tisLibInit = true;<br \/>\n\t}<br \/>\n<\/code><\/p>\n<p>Just call this method before accessing the libraries, and you are done!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The goal of this article is to explain how to support &#8220;shorcuts&#8221; in libraries on Android. On Linux you have this type of structure * \/lib\/x86_64-linux-gnu\/libusb-1.0.so -> Link to libusb-1.0.so.0 * \/lib\/x86_64-linux-gnu\/libusb-1.0.so.0 -> Link to libusb-1.0.so.0.1.0 * \/lib\/x86_64-linux-gnu\/libusb-1.0.so.0.1.0 I need to support some libraries using this naming convention: x.so.4, where you have the version of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[8],"tags":[],"class_list":["post-354","post","type-post","status-publish","format-standard","hentry","category-android"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p50cYU-5I","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/posts\/354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/comments?post=354"}],"version-history":[{"count":0,"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/posts\/354\/revisions"}],"wp:attachment":[{"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/media?parent=354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/categories?post=354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuage.ch\/site\/wp-json\/wp\/v2\/tags?post=354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}