Selaa lähdekoodia

尝试用本地加载so的方式加载media中的so文件,但是x86不兼容

zengjiebin 7 vuotta sitten
vanhempi
commit
c857ebdd53

+ 62 - 14
app/src/main/java/com/sheep/gamegroup/module/plugin/model/Plugin.java

@@ -1,34 +1,82 @@
 package com.sheep.gamegroup.module.plugin.model;
 
+import com.didi.virtualapk.PluginManager;
+import com.kfzs.cfyl.media.MediaApp;
+import com.kfzs.cfyl.share_library.util.ContextHolder;
+import com.sheep.gamegroup.module.plugin.util.SheepPluginUtil;
+import com.sheep.gamegroup.util.LogUtil;
+import com.sheep.gamegroup.util.TestUtil;
+import com.sheep.gamegroup.util.ZipUtil;
+import com.sheep.jiuyan.samllsheep.BuildConfig;
+import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
+
+import java.io.File;
+
 /**
  * Created by realicing on 2018/12/6.
  * realicing@sina.com
  */
 public enum  Plugin {
-    media("com.kfzs.cfyl.media", "apk"),
-    media_zip_so("com.kfzs.cfyl.media", "zip_so"),
+    media("com.kfzs.cfyl.media", ".apk"){
+        @Override
+        public boolean loadPlugin() {
+            if (PluginManager.getInstance(SheepApp.getInstance()).getLoadedPlugin(getPackageName()) == null) {
+//                String cpuAbi = getCPU_ABI();
+//                String pluginPath = String.format(Locale.CHINA, "%s/media_%s.apk", ClassFileHelper.DIR, cpuAbi);
+                String pluginPath = ClassFileHelper.DIR + "/media_release.apk";
+//                LogUtil.println(PluginUtil.class.getSimpleName(), "CPU_ABI =", cpuAbi, "pluginPath =", pluginPath);
+                File file = new File(pluginPath);
+                boolean isUserTestFile = TestUtil.isTest() && file.exists();
+                LogUtil.println("startPlugin", isUserTestFile);
+                File pluginFile = isUserTestFile ? file : SheepPluginUtil.getFile(this);
+                if (!pluginFile.exists()) {
+                    return false;
+                }
+                try {
+                    PluginManager.getInstance(SheepApp.getInstance()).loadPlugin(pluginFile);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+            return super.loadPlugin();
+        }
+    },
+    media_zip_so(BuildConfig.APPLICATION_ID, ".zip") {
+        @Override
+        public boolean loadPlugin() {
+            ContextHolder.loadLibrary = false;//设置为false,代表加载本地so
+            File pluginFile = SheepPluginUtil.getFile(this);
+            ZipUtil.unZip(pluginFile.getAbsolutePath(), ContextHolder.getLocalSoFileDir(), false);
+            return super.loadPlugin();
+        }
+    },
+    media_library(BuildConfig.APPLICATION_ID, "") ,
     ;
-    public static final String TYPE_APK = "apk";
-    public static final String TYPE_ZIP_SO = "zip_so";
     private final String packageName;
-    private final String type;
+    private final String suffix;
 
-    Plugin(String packageName, String type) {
+    Plugin(String packageName, String suffix) {
         this.packageName = packageName;
-        this.type = type;
+        this.suffix = suffix;
     }
 
     public String getPackageName() {
         return packageName;
     }
-    public boolean isApk(){
-        return TYPE_APK.equals(type);
-    }
-    public boolean isZipSo(){
-        return TYPE_ZIP_SO.equals(type);
+
+    private boolean isLoadCgeLibrary;
+    public boolean loadPlugin() {
+        if(isLoadCgeLibrary){
+            return true;
+        }
+        isLoadCgeLibrary = MediaApp.initCgeLibrary(ContextHolder.getContext());
+        return isLoadCgeLibrary;
     }
 
-    public boolean load() {
-        return false;
+    //返回后缀
+    public String getSuffix(){
+        return suffix;
     }
 }

+ 12 - 25
app/src/main/java/com/sheep/gamegroup/module/plugin/util/SheepPluginUtil.java

@@ -8,6 +8,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.didi.virtualapk.PluginManager;
 import com.didi.virtualapk.internal.LoadedPlugin;
 import com.didi.virtualapk.internal.utils.PluginUtil;
+import com.kfzs.cfyl.share_library.util.CallBackAPI;
 import com.sheep.gamegroup.absBase.AbsObserver;
 import com.sheep.gamegroup.model.entity.BaseMessage;
 import com.sheep.gamegroup.model.util.SheepSubscriber;
@@ -55,6 +56,10 @@ public class SheepPluginUtil {
     //检查并更新插件
     public static Observable<Plugin> checkAndRunPlugin(Activity activity, Plugin plugin) {
         return Observable.create((ObservableOnSubscribe<Plugin>) emitter -> {
+            if(TextUtils.isEmpty(plugin.getSuffix())){//后缀为空,不需要下载文件,可以直接使用
+                emitter.onNext(plugin);
+                return;
+            }
             String packageName = plugin.getPackageName();
             String type = SheepPluginUtil.getCPU_ABI();
             int versionCode = BuildConfig.VERSION_CODE;
@@ -67,7 +72,7 @@ public class SheepPluginUtil {
                     .map(clientPackage -> {
                         if (clientPackage != null && clientPackage.getMd_5() != null) {
                             String key = ApiKey.getPackageVersion(packageName, type, versionCode);
-                            File file = getFile(key);
+                            File file = getFile(key, plugin);
                             if (file.exists()) {
                                 if (Md5Util.checkMD5(clientPackage.getMd_5(), file)) {
                                     return null;
@@ -93,26 +98,8 @@ public class SheepPluginUtil {
                     });
         }).subscribeOn(Schedulers.io())
                 .filter(plugin1 -> {
-                    if (PluginManager.getInstance(SheepApp.getInstance()).getLoadedPlugin(plugin1.getPackageName()) == null) {
-//                String cpuAbi = getCPU_ABI();
-//                String pluginPath = String.format(Locale.CHINA, "%s/media_%s.apk", ClassFileHelper.DIR, cpuAbi);
-                        String pluginPath = ClassFileHelper.DIR + "/media_release.apk";
-//                LogUtil.println(PluginUtil.class.getSimpleName(), "CPU_ABI =", cpuAbi, "pluginPath =", pluginPath);
-                        File file = new File(pluginPath);
-                        boolean isUserTestFile = TestUtil.isTest() && file.exists();
-                        LogUtil.println("startPlugin", isUserTestFile);
-                        File pluginFile = isUserTestFile ? file : getFile(plugin1);
-                        if (!pluginFile.exists()) {
-                            return false;
-                        }
-                        try {
-                            PluginManager.getInstance(SheepApp.getInstance()).loadPlugin(pluginFile);
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                            return false;
-                        }
-                    }
-                    return true;
+                    CallBackAPI.get().setPackageName(plugin1.getPackageName());
+                    return plugin1.loadPlugin();
                 });
     }
 
@@ -202,7 +189,7 @@ public class SheepPluginUtil {
 
     public static File getFile(Plugin plugin) {
         String key = getKey(plugin);
-        return getFile(key);
+        return getFile(key, plugin);
     }
 
     public static String getDownloadPluginKey(Plugin plugin) {
@@ -218,10 +205,10 @@ public class SheepPluginUtil {
 
     public static String getFileName(Plugin plugin) {
         String key = getKey(plugin);
-        return key.hashCode() + ".apk";
+        return key.hashCode() + plugin.getSuffix();
     }
 
-    public static File getFile(String key) {
-        return new File(getDir(), key.hashCode() + ".apk");
+    public static File getFile(String key, Plugin plugin) {
+        return new File(getDir(), key.hashCode() + plugin.getSuffix());
     }
 }

+ 1 - 1
app/src/main/java/com/sheep/gamegroup/util/Jump2View.java

@@ -2402,7 +2402,7 @@ public class Jump2View {
      * @param data 视频数据,包括地址与时长,宽高等
      */
     public void goActCutVideo(Activity activity, Video data) {
-        SheepPluginUtil.checkAndRunPlugin(activity, Plugin.media_zip_so)
+        SheepPluginUtil.checkAndRunPlugin(activity, Plugin.media_library)
                 .flatMap((Function<Plugin, ObservableSource<BaseMessage>>) plugin -> SheepApp.getInstance().getNetComponent().getApiService().getVideoTopic())
 //        SheepApp.getInstance().getNetComponent().getApiService().getVideoTopic()
                 .subscribeOn(Schedulers.io())

+ 68 - 0
app/src/main/java/com/sheep/gamegroup/util/ZipUtil.java

@@ -0,0 +1,68 @@
+package com.sheep.gamegroup.util;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Created by realicing on 2018/12/28.
+ * realicing@sina.com
+ */
+public class ZipUtil {
+    /**
+     * 解压zip文件到指定目录
+     * @param zipFile
+     * @param targetDir
+     * @param isNotCover 是否不覆盖
+     */
+    public static void unZip(String zipFile, String targetDir, boolean isNotCover) {
+        int BUFFER = 4096; //这里缓冲区我们使用4KB,
+        String strEntry; //保存每个zip的条目名称
+
+        try {
+            BufferedOutputStream dest; //缓冲输出流
+            FileInputStream fis = new FileInputStream(zipFile);
+            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
+            ZipEntry entry; //每个zip条目的实例
+
+            while ((entry = zis.getNextEntry()) != null) {
+
+                try {
+//                    Log.i("Unzip: ", "=" + entry);
+                    int count;
+                    byte data[] = new byte[BUFFER];
+                    strEntry = entry.getName();
+
+                    File entryFile = new File(new File(targetDir), strEntry);
+                    File entryDir = new File(entryFile.getParent());
+                    if (!entryDir.exists()) {
+                        entryDir.mkdirs();
+                    }
+                    long length = entryFile.length();
+                    long size = entry.getSize();
+                    if (isNotCover && length == size) {
+                        continue;
+                    }
+
+                    FileOutputStream fos = new FileOutputStream(entryFile);
+                    dest = new BufferedOutputStream(fos, BUFFER);
+                    while ((count = zis.read(data, 0, BUFFER)) != -1) {
+                        dest.write(data, 0, count);
+                    }
+                    dest.flush();
+                    dest.close();
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                }
+            }
+            zis.close();
+        } catch (Exception cwj) {
+            cwj.printStackTrace();
+        }
+    }
+}

+ 2 - 2
app/src/main/java/com/sheep/jiuyan/samllsheep/SheepApp.java

@@ -17,7 +17,7 @@ import com.baidu.location.LocationClientOption;
 import com.bumptech.glide.Glide;
 import com.danikula.videocache.HttpProxyCacheServer;
 import com.didi.virtualapk.PluginManager;
-import com.kfzs.cfyl.media.MediaApp;
+import com.kfzs.cfyl.share_library.util.ContextHolder;
 import com.liulishuo.okdownload.OkDownload;
 import com.liulishuo.okdownload.core.dispatcher.DownloadDispatcher;
 import com.sheep.gamegroup.di.components.DaggerNetComponent;
@@ -159,6 +159,7 @@ public class SheepApp extends MultiDexApplication {
         super.onCreate();
         if (AppUtil.isMainProcess(this)) {
             mSheepApp = this;
+            ContextHolder.setContext(this);
             connectAddress = ConnectAddress.sheep.getDefaultConnectAddress();
             registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
             initNet();
@@ -267,7 +268,6 @@ public class SheepApp extends MultiDexApplication {
 //        RemitStoreOnSQLite.setRemitToDBDelayMillis(3000);
         //webView 缓存优化初始化 https://github.com/yale8848/CacheWebView
         WebViewCacheInterceptorInst.getInstance().init(new WebViewCacheInterceptor.Builder(this).setDebug(BuildConfig.DEBUG).setCacheSize(Long.MAX_VALUE));
-        boolean result = MediaApp.initCgeLibrary(this);
 
     }
 

+ 1 - 0
joevideolib/build.gradle

@@ -33,4 +33,5 @@ android {
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation "com.android.support:support-annotations:$supportLibVersion"
+    compileOnly project(':share_library')
 }

+ 3 - 1
joevideolib/src/main/java/Jni/ColorUtils.java

@@ -1,5 +1,7 @@
 package Jni;
 
+import com.kfzs.cfyl.share_library.util.ContextHolder;
+
 /**
  * Created by 杨杰 on 2017/4/19.
  * 颜色格式转换的类
@@ -11,7 +13,7 @@ public class ColorUtils {
 	 * 加载所有相关链接库
 	 */
 	static {
-		System.loadLibrary("colorutils");
+		ContextHolder.loadLibrary("colorutils");
 	}
 
 	public static native byte[] rgb2yuvfloat(byte[] rgbs, int size, int width, int height);

+ 10 - 8
joevideolib/src/main/java/Jni/FFmpegCmd.java

@@ -2,6 +2,8 @@ package Jni;
 
 import android.support.annotation.Keep;
 
+import com.kfzs.cfyl.share_library.util.ContextHolder;
+
 import VideoHandle.OnEditorListener;
 
 /**
@@ -14,14 +16,14 @@ public class FFmpegCmd {
 	 * 加载所有相关链接库
 	 */
 	static {
-		System.loadLibrary("avutil");
-		System.loadLibrary("avcodec");
-		System.loadLibrary("swresample");
-		System.loadLibrary("avformat");
-		System.loadLibrary("swscale");
-		System.loadLibrary("avfilter");
-		System.loadLibrary("avdevice");
-		System.loadLibrary("joe_ffmpeg");
+        ContextHolder.loadLibrary("avutil");
+        ContextHolder.loadLibrary("avcodec");
+        ContextHolder.loadLibrary("swresample");
+        ContextHolder.loadLibrary("avformat");
+        ContextHolder.loadLibrary("swscale");
+        ContextHolder.loadLibrary("avfilter");
+        ContextHolder.loadLibrary("avdevice");
+        ContextHolder.loadLibrary("joe_ffmpeg");
 	}
 
 	private static OnEditorListener listener;

+ 1 - 0
media/cge_library/build.gradle

@@ -39,4 +39,5 @@ android {
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation "com.android.support:appcompat-v7:$supportLibVersion"
+    compileOnly project(':share_library')
 }

+ 3 - 1
media/cge_library/src/main/java/org/wysaid/nativePort/CGEFaceTracker.java

@@ -3,6 +3,8 @@ package org.wysaid.nativePort;
 import android.graphics.Bitmap;
 import android.graphics.PointF;
 
+import com.kfzs.cfyl.share_library.util.ContextHolder;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
@@ -17,7 +19,7 @@ public class CGEFaceTracker {
     static {
         //You can ignore the tracker libraries below(for decreasing your package size, just delete the .so file below), if you don't want any face features.
 //        System.loadLibrary("opencv_java3");  // OpenCV is statically built into FaceTracker now.
-        System.loadLibrary("FaceTracker");
+        ContextHolder.loadLibrary("FaceTracker");
     }
 
     //临时处理, 后续将扩展更复杂的操作

+ 5 - 3
media/cge_library/src/main/java/org/wysaid/nativePort/NativeLibraryLoader.java

@@ -1,14 +1,16 @@
 package org.wysaid.nativePort;
 
+import com.kfzs.cfyl.share_library.util.ContextHolder;
+
 /**
  * Created by wangyang on 15/7/30.
  */
 public class NativeLibraryLoader {
 
     public static void load() {
-        System.loadLibrary("ffmpeg");
-        System.loadLibrary("CGE");
-        System.loadLibrary("CGEExt");
+        ContextHolder.loadLibrary("ffmpeg");
+        ContextHolder.loadLibrary("CGE");
+        ContextHolder.loadLibrary("CGEExt");
         CGEFFmpegNativeLibrary.avRegisterAll();
     }
 

+ 8 - 16
media/share_library/src/main/java/com/kfzs/cfyl/share_library/util/CallBackAPI.java

@@ -26,16 +26,16 @@ public class CallBackAPI {
         return instance;
     }
 
-    private boolean isVirtualapkLoadMedia = false;
+    private String packageName = "com.kfzs.cfyl.media";
+
+    public void setPackageName(String packageName) {
+        this.packageName = packageName;
+    }
 
     //剪切视频并选择主题
     public void goCutVideo(Activity activity, Video video, ArrayList<String> arrayList) {
         Intent intent = new Intent();
-        if (isVirtualapkLoadMedia) {
-            intent.setClassName("com.kfzs.cfyl.media", "com.kfzs.cfyl.media.activity.ActCutVideo");
-        } else {
-            intent.setClassName(activity.getPackageName(), "com.kfzs.cfyl.media.activity.ActCutVideo");
-        }
+        intent.setClassName(packageName, "com.kfzs.cfyl.media.activity.ActCutVideo");
         intent.putExtra(Integer.class.getSimpleName(), Constant.MEDIA_ACTION_CUT_VIDEO);
         intent.putExtra(String.class.getSimpleName(), JSONObject.toJSONString(video));
         intent.putExtra(ArrayList.class.getSimpleName(), arrayList);
@@ -45,11 +45,7 @@ public class CallBackAPI {
     //编辑视频
     public void goEditVideo(Activity activity, Serializable data) {
         Intent intent = new Intent();
-        if (isVirtualapkLoadMedia) {
-            intent.setClassName("com.kfzs.cfyl.media", "com.kfzs.cfyl.media.activity.ActEditVideo");
-        } else {
-            intent.setClassName(activity.getPackageName(), "com.kfzs.cfyl.media.activity.ActEditVideo");
-        }
+        intent.setClassName(packageName, "com.kfzs.cfyl.media.activity.ActEditVideo");
         intent.putExtra(Integer.class.getSimpleName(), Constant.MEDIA_ACTION_EDIT_VIDEO);
         intent.putExtra(Video.class.getSimpleName(), data);
         activity.startActivityForResult(intent, Constant.MEDIA_ACTION_EDIT_VIDEO);
@@ -58,11 +54,7 @@ public class CallBackAPI {
     //编辑视频
     public void goAct(Activity activity, String act) {
         Intent intent = new Intent();
-        if (isVirtualapkLoadMedia) {
-            intent.setClassName("com.kfzs.cfyl.media", "com.kfzs.cfyl.media.activity." + act);
-        } else {
-            intent.setClassName(activity.getPackageName(), "com.kfzs.cfyl.media.activity." + act);
-        }
+        intent.setClassName(packageName, "com.kfzs.cfyl.media.activity." + act);
         activity.startActivityForResult(intent, Constant.MEDIA_ACTION_EDIT_VIDEO);
     }
 }

+ 61 - 0
media/share_library/src/main/java/com/kfzs/cfyl/share_library/util/ContextHolder.java

@@ -0,0 +1,61 @@
+package com.kfzs.cfyl.share_library.util;
+
+import android.content.Context;
+
+import java.io.File;
+
+/**
+ * Created by realicing on 2018/12/28.
+ * realicing@sina.com
+ */
+public class ContextHolder {
+
+    private static Context context;
+    public static void setContext(Context context){
+        ContextHolder.context = context;
+    }
+
+    public static Context getContext() {
+        return context;
+    }
+
+    //直接用系统的方法来加载so
+    public static boolean loadLibrary = true;
+
+    //尝试加载本地保存的so文件
+    public static void loadLibrary(String lib) {
+        if(loadLibrary){
+            System.loadLibrary(lib);
+            return;
+        }
+        String filePath = getLocalSoFilePath(lib);
+        if(filePath != null) {
+            System.load(filePath);
+        }
+    }
+
+    //获取so文件目录
+    public static String getLocalSoFileDir() {
+        if(context == null)
+            return null;
+        return context.getDir("so", Context.MODE_PRIVATE).getAbsolutePath();
+    }
+    //获取so文件路径
+    public static String getLocalSoFilePath(String lib) {
+        if(context == null)
+            return null;
+        String name = lib;
+        String start = "lib";
+//        Log.i("Unzip", "getLocalSoFilePath 1 "+name);
+        if(!lib.startsWith(start)){
+            name = start + lib;
+        }
+        String end = ".so";
+        if(!lib.endsWith(end)){
+            name += end;
+        }
+//        Log.i("Unzip:: ", "getLocalSoFilePath 2 "+name);
+        File soFile = new File(context.getDir("so", Context.MODE_PRIVATE), name);
+        return soFile.exists() ? soFile.getAbsolutePath() : null;
+    }
+}