// Path: lib_common/src/main/java/com/guiying/module/common/utils/Utils.java
// public class Utils {
// 
//     private static Context context;
// 
//     private Utils() {
//         throw new UnsupportedOperationException("u can't instantiate me...");
//     }
// 
//     /**
//      * 初始化工具类
//      *
//      * @param context 上下文
//      */
//     public static void init(Context context) {
//         Utils.context = context.getApplicationContext();
//     }
// 
//     /**
//      * 获取ApplicationContext
//      *
//      * @return ApplicationContext
//      */
//     public static Context getContext() {
//         if (context != null) return context;
//         throw new NullPointerException("u should init first");
//     }
// 
//     /**
//      * View获取Activity的工具
//      *
//      * @param view view
//      * @return Activity
//      */
//     public static
//     @NonNull
//     Activity getActivity(View view) {
//         Context context = view.getContext();
// 
//         while (context instanceof ContextWrapper) {
//             if (context instanceof Activity) {
//                 return (Activity) context;
//             }
//             context = ((ContextWrapper) context).getBaseContext();
//         }
// 
//         throw new IllegalStateException("View " + view + " is not attached to an Activity");
//     }
// 
//     /**
//      * 全局获取String的方法
//      *
//      * @param id 资源Id
//      * @return String
//      */
//     public static String getString(@StringRes int id) {
//         return context.getResources().getString(id);
//     }
// 
//     /**
//      * 判断App是否是Debug版本
//      *
//      * @return {@code true}: 是<br>{@code false}: 否
//      */
//     public static boolean isAppDebug() {
//         if (StringUtils.isSpace(context.getPackageName())) return false;
//         try {
//             PackageManager pm = context.getPackageManager();
//             ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(), 0);
//             return ai != null && (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
//         } catch (PackageManager.NameNotFoundException e) {
//             e.printStackTrace();
//             return false;
//         }
//     }
// 
// 
//     /**
//      * The {@code fragment} is added to the container view with id {@code frameId}. The operation is
//      * performed by the {@code fragmentManager}.
//      */
//     public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager,
//                                              @NonNull Fragment fragment, int frameId) {
//         checkNotNull(fragmentManager);
//         checkNotNull(fragment);
//         FragmentTransaction transaction = fragmentManager.beginTransaction();
//         transaction.add(frameId, fragment);
//         transaction.commit();
//     }
// 
// 
//     public static <T> T checkNotNull(T obj) {
//         if (obj == null) {
//             throw new NullPointerException();
//         }
//         return obj;
//     }
// 
// }


import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.Keep;
import android.util.Log;
import com.guiying.module.common.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import dalvik.system.DexFile;
    public static List<String> getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException {
        ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
        File sourceApk = new File(applicationInfo.sourceDir);

        List<String> sourcePaths = new ArrayList<>();
        sourcePaths.add(applicationInfo.sourceDir); //add the default apk path

        //the prefix of extracted file, ie: test.classes
        String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;

        //如果VM已经支持了MultiDex，就不要去Secondary Folder加载 Classesx.zip了，那里已经么有了
        //通过是否存在sp中的multidex.version是不准确的，因为从低版本升级上来的用户，是包含这个sp配置的
        if (!isVMMultidexCapable()) {
            //the total dex numbers
            int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1);
            File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);

            for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {
                //for each dex file, ie: test.classes2.zip, test.classes3.zip...
                String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
                File extractedFile = new File(dexDir, fileName);
                if (extractedFile.isFile()) {
                    sourcePaths.add(extractedFile.getAbsolutePath());
                    //we ignore the verify zip part
                } else {
                    throw new IOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'");
                }
            }
        }

// Path: lib_common/src/main/java/com/guiying/module/common/utils/Utils.java
// public class Utils {
// 
//     private static Context context;
// 
//     private Utils() {
//         throw new UnsupportedOperationException("u can't instantiate me...");
//     }
// 
//     /**
//      * 初始化工具类
//      *
//      * @param context 上下文
//      */
//     public static void init(Context context) {
//         Utils.context = context.getApplicationContext();
//     }
// 
//     /**
//      * 获取ApplicationContext
//      *
//      * @return ApplicationContext
//      */
//     public static Context getContext() {
//         if (context != null) return context;
//         throw new NullPointerException("u should init first");
//     }
// 
//     /**
//      * View获取Activity的工具
//      *
//      * @param view view
//      * @return Activity
//      */
//     public static
//     @NonNull
//     Activity getActivity(View view) {
//         Context context = view.getContext();
// 
//         while (context instanceof ContextWrapper) {
//             if (context instanceof Activity) {
//                 return (Activity) context;
//             }
//             context = ((ContextWrapper) context).getBaseContext();
//         }
// 
//         throw new IllegalStateException("View " + view + " is not attached to an Activity");
//     }
// 
//     /**
//      * 全局获取String的方法
//      *
//      * @param id 资源Id
//      * @return String
//      */
//     public static String getString(@StringRes int id) {
//         return context.getResources().getString(id);
//     }
// 
//     /**
//      * 判断App是否是Debug版本
//      *
//      * @return {@code true}: 是<br>{@code false}: 否
//      */
//     public static boolean isAppDebug() {
//         if (StringUtils.isSpace(context.getPackageName())) return false;
//         try {
//             PackageManager pm = context.getPackageManager();
//             ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(), 0);
//             return ai != null && (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
//         } catch (PackageManager.NameNotFoundException e) {
//             e.printStackTrace();
//             return false;
//         }
//     }
// 
// 
//     /**
//      * The {@code fragment} is added to the container view with id {@code frameId}. The operation is
//      * performed by the {@code fragmentManager}.
//      */
//     public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager,
//                                              @NonNull Fragment fragment, int frameId) {
//         checkNotNull(fragmentManager);
//         checkNotNull(fragment);
//         FragmentTransaction transaction = fragmentManager.beginTransaction();
//         transaction.add(frameId, fragment);
//         transaction.commit();
//     }
// 
// 
//     public static <T> T checkNotNull(T obj) {
//         if (obj == null) {
//             throw new NullPointerException();
//         }
//         return obj;
//     }
// 
// }


// Path: lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.Keep;
import android.util.Log;
import com.guiying.module.common.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import dalvik.system.DexFile;

    public static List<String> getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException {
        ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
        File sourceApk = new File(applicationInfo.sourceDir);

        List<String> sourcePaths = new ArrayList<>();
        sourcePaths.add(applicationInfo.sourceDir); //add the default apk path

        //the prefix of extracted file, ie: test.classes
        String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;

        //如果VM已经支持了MultiDex，就不要去Secondary Folder加载 Classesx.zip了，那里已经么有了
        //通过是否存在sp中的multidex.version是不准确的，因为从低版本升级上来的用户，是包含这个sp配置的
        if (!isVMMultidexCapable()) {
            //the total dex numbers
            int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1);
            File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);

            for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {
                //for each dex file, ie: test.classes2.zip, test.classes3.zip...
                String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
                File extractedFile = new File(dexDir, fileName);
                if (extractedFile.isFile()) {
                    sourcePaths.add(extractedFile.getAbsolutePath());
                    //we ignore the verify zip part
                } else {
                    throw new IOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'");
                }
            }
        }

        if (Utils.isAppDebug()) {