private static void callPluginApplicationOnCreate(PluginDescriptor pluginDescriptor) {

    Application application = null;

    if (pluginDescriptor.getPluginApplication() == null
        && pluginDescriptor.getPluginClassLoader() != null) {
      try {
        LogUtil.d("创建插件Application", pluginDescriptor.getApplicationName());
        application =
            Instrumentation.newApplication(
                pluginDescriptor
                    .getPluginClassLoader()
                    .loadClass(pluginDescriptor.getApplicationName()),
                pluginDescriptor.getPluginContext());
        pluginDescriptor.setPluginApplication(application);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }

    // 安装ContentProvider
    PluginInjector.installContentProviders(
        sApplication, pluginDescriptor.getProviderInfos().values());

    // 执行onCreate
    if (application != null) {
      application.onCreate();
    }

    changeListener.onPluginStarted(pluginDescriptor.getPackageName());
  }
  @SuppressWarnings("rawtypes")
  public static Class loadPluginClassByName(String clazzName) {

    PluginDescriptor pluginDescriptor = getPluginDescriptorByClassName(clazzName);

    if (pluginDescriptor != null) {

      ensurePluginInited(pluginDescriptor);

      DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader();

      try {
        Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName);
        LogUtil.d("loadPluginClass Success for clazzName ", clazzName);
        return pluginClazz;
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (java.lang.IllegalAccessError illegalAccessError) {
        illegalAccessError.printStackTrace();
        throw new IllegalAccessError(
            "出现这个异常最大的可能是插件dex和" + "宿主dex包含了相同的class导致冲突, " + "请检查插件的编译脚本,确保排除了所有公共依赖库的jar");
      }
    }

    LogUtil.e("loadPluginClass Fail for clazzName ", clazzName);

    return null;
  }
  /**
   * 根据插件中的classId加载一个插件中的class
   *
   * @param clazzId
   * @return
   */
  @SuppressWarnings("rawtypes")
  public static Class loadPluginFragmentClassById(String clazzId) {

    PluginDescriptor pluginDescriptor = getPluginDescriptorByFragmenetId(clazzId);

    if (pluginDescriptor != null) {

      ensurePluginInited(pluginDescriptor);

      DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader();

      String clazzName = pluginDescriptor.getPluginClassNameById(clazzId);
      if (clazzName != null) {
        try {
          Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName);
          LogUtil.d("loadPluginClass for clazzId", clazzId, "clazzName", clazzName, "success");
          return pluginClazz;
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
      }
    }

    LogUtil.e("loadPluginClass for clazzId", clazzId, "fail");

    return null;
  }
  /**
   * 构造插件信息
   *
   * @param
   */
  static void ensurePluginInited(PluginDescriptor pluginDescriptor) {
    if (pluginDescriptor != null) {
      DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader();
      if (pluginClassLoader == null) {
        LogUtil.d("正在初始化插件Resources, DexClassLoader, Context, Application ");

        LogUtil.d("是否为独立插件", pluginDescriptor.isStandalone());

        Resources pluginRes =
            PluginCreator.createPluginResource(
                sApplication, pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone());

        pluginClassLoader =
            PluginCreator.createPluginClassLoader(
                pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone());
        Context pluginContext =
            PluginCreator.createPluginApplicationContext(
                pluginDescriptor, sApplication, pluginRes, pluginClassLoader);

        pluginContext.setTheme(sApplication.getApplicationContext().getApplicationInfo().theme);
        pluginDescriptor.setPluginContext(pluginContext);
        pluginDescriptor.setPluginClassLoader(pluginClassLoader);

        // 使用了openAtlasExtention之后就不需要Public.xml文件了
        // checkPluginPublicXml(pluginDescriptor, pluginRes);

        callPluginApplicationOnCreate(pluginDescriptor);

        LogUtil.d("初始化插件" + pluginDescriptor.getPackageName() + "完成");
      }
    }
  }
  @SuppressWarnings("rawtypes")
  public static Class loadPluginClassByName(String clazzName) {

    PluginDescriptor pluginDescriptor = getPluginDescriptorByClassName(clazzName);

    if (pluginDescriptor != null) {

      ensurePluginInited(pluginDescriptor);

      DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader();

      try {
        Class pluginClazz = ((ClassLoader) pluginClassLoader).loadClass(clazzName);
        LogUtil.d("loadPluginClass Success for clazzName ", clazzName);
        return pluginClazz;
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (java.lang.IllegalAccessError illegalAccessError) {
        illegalAccessError.printStackTrace();
      }
    }

    LogUtil.e("loadPluginClass Fail for clazzName ", clazzName);

    return null;
  }
  /**
   * 构造插件信息
   *
   * @param
   */
  static void ensurePluginInited(PluginDescriptor pluginDescriptor) {
    if (pluginDescriptor != null) {
      DexClassLoader pluginClassLoader = pluginDescriptor.getPluginClassLoader();
      if (pluginClassLoader == null) {
        LogUtil.e(
            "正在初始化插件"
                + pluginDescriptor.getPackageName()
                + "Resources, DexClassLoader, Context, Application");

        LogUtil.d("是否为独立插件", pluginDescriptor.isStandalone());

        Resources pluginRes = PluginCreator.createPluginResource(sApplication, pluginDescriptor);

        pluginClassLoader =
            PluginCreator.createPluginClassLoader(
                pluginDescriptor.getInstalledPath(),
                pluginDescriptor.isStandalone(),
                pluginDescriptor.getDependencies());
        Context pluginContext =
            PluginCreator.createPluginContext(
                pluginDescriptor, sApplication, pluginRes, pluginClassLoader);

        // 插件Context默认主题设置为插件application主题
        pluginContext.setTheme(pluginDescriptor.getApplicationTheme());
        pluginDescriptor.setPluginContext(pluginContext);
        pluginDescriptor.setPluginClassLoader(pluginClassLoader);

        try {
          ActivityThread.installPackageInfo(getApplicatoin(), pluginDescriptor.getPackageName());
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }

        callPluginApplicationOnCreate(pluginDescriptor);

        LogUtil.e("初始化插件" + pluginDescriptor.getPackageName() + "完成");
      }
    }
  }
  /**
   * for eclipse & ant with public.xml
   *
   * <p>unused
   *
   * @param pluginDescriptor
   * @param res
   * @return
   */
  private static boolean checkPluginPublicXml(PluginDescriptor pluginDescriptor, Resources res) {

    // "plugin_layout_1"资源id时由public.xml配置的
    // 如果没有检测到这个资源,说明编译时没有引入public.xml,
    // 这里直接抛个异常出去。
    // 不同的系统版本获取id的方式不同,
    // 三星4.x等系统适用
    int publicStub =
        res.getIdentifier("plugin_layout_1", "layout", pluginDescriptor.getPackageName());
    if (publicStub == 0) {
      // 小米5.x等系统适用
      publicStub = res.getIdentifier("plugin_layout_1", "layout", sApplication.getPackageName());
    }
    if (publicStub == 0) {
      try {
        // 如果以上两种方式都检测失败,最后尝试通过反射检测
        Class layoutClass =
            ((ClassLoader) pluginDescriptor.getPluginClassLoader())
                .loadClass(pluginDescriptor.getPackageName() + ".R$layout");
        Integer layouId = (Integer) RefInvoker.getFieldObject(null, layoutClass, "plugin_layout_1");
        if (layouId != null) {
          publicStub = layouId;
        }
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
    }

    if (publicStub == 0) {
      throw new IllegalStateException(
          "\n插件工程没有使用public.xml给资源id分组!!!\n"
              + "插件工程没有使用public.xml给资源id分组!!!\n"
              + "插件工程没有使用public.xml给资源id分组!!!\n"
              + "重要的事情讲三遍!!!");
    }
    return true;
  }