diff --git a/README.md b/README.md index a6946dd8..331320b2 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,19 @@

[![license](http://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat)](https://github.com/Qihoo360/RePlugin/blob/master/LICENSE) -[![Release Version](https://img.shields.io/badge/release-2.3.1-brightgreen.svg)](https://github.com/Qihoo360/RePlugin/releases) +[![Release Version](https://img.shields.io/badge/release-2.3.2-brightgreen.svg)](https://github.com/Qihoo360/RePlugin/releases) -## 活动通知 -移动技术最新活动通知:9月1号360移动技术开放日 http://t.cn/RDiNru9 +## 通知 + +**360开源又一力作——[ArgusAPM移动性能监控平台](https://github.com/Qihoo360/ArgusAPM)** + +[ArgusAPM](https://github.com/Qihoo360/ArgusAPM)是360手机卫士客户端团队继RePlugin之后开源的又一个重量级开源项目。ArgusAPM是360移动端产品使用的可视化性能监控平台,为移动端APP提供性能监控与管理,可以迅速发现和定位各类APP性能和使用问题,帮助APP不断的提升用户体验。 + + +**360移动技术最新活动通知:** + +2018年12月16日,360移动性能开放日邀您参加,届时将会有360、美团技术大牛为大家分享Android、iOS性能监控实践。 +欢迎报名参加,戳戳戳!!!-->https://mp.weixin.qq.com/s/-7DCnXI_EBMBwYG_PUuUDg ## RePlugin —— A flexible, stable, easy-to-use Android Plug-in Framework diff --git a/README_CN.md b/README_CN.md index 85b84bc4..9b1e8fff 100644 --- a/README_CN.md +++ b/README_CN.md @@ -6,9 +6,19 @@ [![license](http://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat)](https://github.com/Qihoo360/RePlugin/blob/master/LICENSE) -[![Release Version](https://img.shields.io/badge/release-2.3.1-brightgreen.svg)](https://github.com/Qihoo360/RePlugin/releases) +[![Release Version](https://img.shields.io/badge/release-2.3.2-brightgreen.svg)](https://github.com/Qihoo360/RePlugin/releases) +## 通知 +**360开源又一力作——[ArgusAPM移动性能监控平台](https://github.com/Qihoo360/ArgusAPM)** + +[ArgusAPM](https://github.com/Qihoo360/ArgusAPM)是360手机卫士客户端团队继RePlugin之后开源的又一个重量级开源项目。ArgusAPM是360移动端产品使用的可视化性能监控平台,为移动端APP提供性能监控与管理,可以迅速发现和定位各类APP性能和使用问题,帮助APP不断的提升用户体验。 + + +**360移动技术最新活动通知:** + +2018年12月16日,360移动性能开放日邀您参加,届时将会有360、美团技术大牛为大家分享Android、iOS性能监控实践。 +欢迎报名参加,戳戳戳!!!-->https://mp.weixin.qq.com/s/-7DCnXI_EBMBwYG_PUuUDg ## RePlugin —— 历经三年多考验,数亿设备使用的,稳定占坑类插件化方案 diff --git a/deploy.sh b/deploy.sh index 0f37f936..09ef8989 100755 --- a/deploy.sh +++ b/deploy.sh @@ -14,7 +14,7 @@ __gradle_exec(){ if [[ -x gradlew ]];then ./gradlew ${@}; else gradle ${@}; fi; __rp_deploy_project(){ [[ ! -d ${1} ]] && echo ">>> INVALID ${1}!!! <<<" && return # execute deploying - echo ">>> ${1} <<<" && __gradle_exec -p ${1} clean bintrayUpload + echo ">>> ${1} <<<" && cd ${1} && __gradle_exec -p ${1} clean bintrayUpload # revert changed files git checkout ${1} } diff --git a/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/RePlugin.groovy b/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/RePlugin.groovy index efa60a61..9c056d07 100644 --- a/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/RePlugin.groovy +++ b/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/RePlugin.groovy @@ -72,8 +72,7 @@ public class Replugin implements Plugin { generateHostConfigTask.group = AppConstant.TASKS_GROUP //depends on build config task - String generateBuildConfigTaskName = variant.getVariantData().getScope().getGenerateBuildConfigTask().name - def generateBuildConfigTask = project.tasks.getByName(generateBuildConfigTaskName) + def generateBuildConfigTask = variant.getGenerateBuildConfig() if (generateBuildConfigTask) { generateHostConfigTask.dependsOn generateBuildConfigTask generateBuildConfigTask.finalizedBy generateHostConfigTask @@ -89,8 +88,7 @@ public class Replugin implements Plugin { generateBuiltinJsonTask.group = AppConstant.TASKS_GROUP //depends on mergeAssets Task - String mergeAssetsTaskName = variant.getVariantData().getScope().getMergeAssetsTask().name - def mergeAssetsTask = project.tasks.getByName(mergeAssetsTaskName) + def mergeAssetsTask = variant.getMergeAssets() if (mergeAssetsTask) { generateBuiltinJsonTask.dependsOn mergeAssetsTask mergeAssetsTask.finalizedBy generateBuiltinJsonTask @@ -151,10 +149,8 @@ public class Replugin implements Plugin { } showPluginsTask.group = AppConstant.TASKS_GROUP - //get mergeAssetsTask name - String mergeAssetsTaskName = variant.getVariantData().getScope().getMergeAssetsTask().name - //get real gradle task - def mergeAssetsTask = project.tasks.getByName(mergeAssetsTaskName) + //get mergeAssetsTask name, get real gradle task + def mergeAssetsTask = variant.getMergeAssets() //depend on mergeAssetsTask so that assets have been merged if (mergeAssetsTask) { diff --git a/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/creator/impl/json/PluginBuiltinJsonCreator.groovy b/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/creator/impl/json/PluginBuiltinJsonCreator.groovy index 6eb82b4c..a6cc6ffd 100644 --- a/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/creator/impl/json/PluginBuiltinJsonCreator.groovy +++ b/replugin-host-gradle/src/main/groovy/com/qihoo360/replugin/gradle/host/creator/impl/json/PluginBuiltinJsonCreator.groovy @@ -35,11 +35,8 @@ public class PluginBuiltinJsonCreator implements IFileCreator { def PluginBuiltinJsonCreator(def project, def variant, def cfg) { this.config = cfg this.variant = variant - //make sure processResources Task execute after mergeAssets Task - String mergeAssetsTaskName = variant.getVariantData().getScope().getMergeAssetsTask().name - //get real gradle task - def mergeAssetsTask = project.tasks.getByName(mergeAssetsTaskName) - fileDir = mergeAssetsTask.outputDir + //make sure processResources Task execute after mergeAssets Task, get real gradle task + fileDir = variant.getMergeAssets()?.outputDir fileName = config.builtInJsonFileName } @@ -56,7 +53,7 @@ public class PluginBuiltinJsonCreator implements IFileCreator { @Override String getFileContent() { //查找插件文件并抽取信息,如果没有就直接返回null - File pluginDirFile = new File(fileDir.getAbsolutePath() + File.separator + config.pluginDir) + File pluginDirFile = new File(fileDir?.getAbsolutePath() + File.separator + config.pluginDir) if (!pluginDirFile.exists()) { println "${AppConstant.TAG} The ${pluginDirFile.absolutePath} does not exist " println "${AppConstant.TAG} pluginsInfo=null" diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/StubProcessManager.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/StubProcessManager.java index 4a56e1a4..c6d46f11 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/StubProcessManager.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/StubProcessManager.java @@ -17,7 +17,6 @@ import static com.qihoo360.replugin.helper.LogDebug.LOG; import static com.qihoo360.replugin.helper.LogDebug.PLUGIN_TAG; import static com.qihoo360.replugin.helper.LogRelease.LOGR; - /** * @author RePlugin Team * dec: 坑位进程管理 buyuntao diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/V5FileInfo.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/V5FileInfo.java index 08fc88ef..5438e8d9 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/V5FileInfo.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/V5FileInfo.java @@ -421,7 +421,7 @@ final PluginInfo updateV5FileTo(Context context, File dir, boolean checkOverride if (target.exists()) { FileUtils.forceDelete(target); } - + // 更名 FileUtils.moveFile(tmpfile, target); return pi; diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginCallbacks.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginCallbacks.java index 5e155c4c..c2696540 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginCallbacks.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginCallbacks.java @@ -21,8 +21,8 @@ import android.content.SharedPreferences; import com.qihoo360.loader2.PluginContext; -import com.qihoo360.replugin.utils.pkg.PackageFilesUtil; import com.qihoo360.replugin.model.PluginInfo; +import com.qihoo360.replugin.utils.pkg.PackageFilesUtil; import java.io.InputStream; diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginConfig.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginConfig.java index a1775a59..df90ec61 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginConfig.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/RePluginConfig.java @@ -208,7 +208,7 @@ public RePluginConfig setMoveFileWhenInstalling(boolean moveFileWhenInstalling) * 获取宿主的 BuildID * * @return 宿主的BuildID - * @since 2.2.2 + * @since 2.0.0 */ public String getHostBuildID() { return hostBuildID; @@ -220,7 +220,7 @@ public String getHostBuildID() { * * @param buildID 宿主的BuildID * @return RePluginConfig自己。这样可以连环调用set方法 - * @since 2.2.2 + * @since 2.0.0 */ public RePluginConfig setHostBuild(String buildID) { if (!checkAllowModify()) { @@ -233,7 +233,7 @@ public RePluginConfig setHostBuild(String buildID) { /** * 获取宿主的 VersionName * - * @since 2.2.2 + * @since 2.0.0 */ public String getHostVersionName() { return hostVersionName; @@ -244,7 +244,7 @@ public String getHostVersionName() { * * @param versionName 宿主的VersionName * @return RePluginConfig自己。这样可以连环调用set方法 - * @since 2.2.2 + * @since 2.0.0 */ public RePluginConfig setHostVersionName(String versionName) { if (!checkAllowModify()) { @@ -258,7 +258,6 @@ public RePluginConfig setHostVersionName(String versionName) { * 获取宿主的VersionBuild号 * * @return - * @since 2.2.2 */ public String getHostVersionBuild() { return RePlugin.getConfig().getHostVersionName() + "." + RePlugin.getConfig().getHostBuildID(); diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/component/provider/PluginProviderClient.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/component/provider/PluginProviderClient.java index 3cc51842..8787be39 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/component/provider/PluginProviderClient.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/component/provider/PluginProviderClient.java @@ -77,7 +77,7 @@ public static Cursor query(Context c, Uri uri, String[] projection, String selec * 调用插件里的Provider * @see android.content.ContentResolver#query(Uri, String[], String, String[], String, CancellationSignal) */ - @TargetApi(16) + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static Cursor query(Context c, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) { Uri turi = toCalledUri(c, uri); return c.getContentResolver().query(turi, projection, selection, selectionArgs, sortOrder, cancellationSignal); diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/helper/LogDebug.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/helper/LogDebug.java index ca69e683..78f73fe8 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/helper/LogDebug.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/helper/LogDebug.java @@ -265,8 +265,5 @@ public static int printPluginInfo(PluginInfo pi, int load) { */ public static final String MISC_TAG = "ws002"; - /** - * createClassLoader TAG - */ public static final String LOADER_TAG = "createClassLoader"; } diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java index f9df75ef..51cb7dd8 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java @@ -35,22 +35,19 @@ import com.qihoo360.loader2.VMRuntimeCompat; import com.qihoo360.replugin.RePlugin; import com.qihoo360.replugin.RePluginInternal; -import com.qihoo360.replugin.helper.JSONHelper; import com.qihoo360.replugin.helper.LogDebug; import com.qihoo360.replugin.utils.FileUtils; import org.json.JSONException; import org.json.JSONObject; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -108,9 +105,23 @@ public class PluginInfo implements Serializable, Parcelable, Cloneable { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public static final int FRAMEWORK_VERSION_UNKNOWN = 0; - - private transient JSONObject mJson; - private String mJsonText; + public static final String PI_PKGNAME = "pkgname"; // √ + public static final String PI_ALI = "ali"; // √ + public static final String PI_LOW = "low"; // √ + public static final String PI_HIGH = "high"; // √ + public static final String PI_VER = "ver"; // √ + public static final String PI_PATH = "path"; + public static final String PI_TYPE = "type"; + public static final String PI_NAME = "name"; // √ + public static final String PI_UPINFO = "upinfo"; + public static final String PI_DELINFO = "delinfo"; + public static final String PI_COVERINFO = "coverinfo"; + public static final String PI_COVER = "cover"; + public static final String PI_VERV = "verv"; + public static final String PI_USED = "used"; + public static final String PI_FRM_VER = "frm_ver"; + + private transient final Map mJson = new ConcurrentHashMap(1 << 4); // 若插件需要更新,则会有此值 private PluginInfo mPendingUpdate; @@ -132,11 +143,10 @@ private PluginInfo(JSONObject jo) { } private PluginInfo(String name, int low, int high, int ver) { - mJson = new JSONObject(); - JSONHelper.putNoThrows(mJson, "name", name); - JSONHelper.putNoThrows(mJson, "low", low); - JSONHelper.putNoThrows(mJson, "high", high); - JSONHelper.putNoThrows(mJson, "ver", ver); + put(PI_NAME, name); + put(PI_LOW, low); + put(PI_HIGH, high); + put(PI_VER, ver); } private PluginInfo(String pkgName, String alias, int low, int high, int version, String path, int type) { @@ -148,12 +158,11 @@ private PluginInfo(String pkgName, String alias, int low, int high, int version, high = Constant.ADAPTER_COMPATIBLE_VERSION; } - mJson = new JSONObject(); - JSONHelper.putNoThrows(mJson, "pkgname", pkgName); - JSONHelper.putNoThrows(mJson, "ali", alias); - JSONHelper.putNoThrows(mJson, "name", makeName(pkgName, alias)); - JSONHelper.putNoThrows(mJson, "low", low); - JSONHelper.putNoThrows(mJson, "high", high); + put(PI_PKGNAME, pkgName); + put(PI_ALI, alias); + put(PI_NAME, makeName(pkgName, alias)); + put(PI_LOW, low); + put(PI_HIGH, high); setVersion(version); setPath(path); @@ -161,28 +170,31 @@ private PluginInfo(String pkgName, String alias, int low, int high, int version, } private void initPluginInfo(JSONObject jo) { - mJson = jo; - + final Iterator keys = jo.keys(); + while (keys.hasNext()) { + final String k = keys.next(); + put(k, jo.opt(k)); + } // 缓存“待更新”的插件信息 - JSONObject ujo = jo.optJSONObject("upinfo"); + final JSONObject ujo = jo.optJSONObject(PI_UPINFO); if (ujo != null) { - mPendingUpdate = new PluginInfo(ujo); + setPendingUpdate(new PluginInfo(ujo)); } // 缓存“待卸载”的插件信息 - JSONObject djo = jo.optJSONObject("delinfo"); + final JSONObject djo = jo.optJSONObject(PI_DELINFO); if (djo != null) { - mPendingDelete = new PluginInfo(djo); + setPendingDelete(new PluginInfo(djo)); } // 缓存"待覆盖安装"的插件信息 - JSONObject cjo = jo.optJSONObject("coverinfo"); + final JSONObject cjo = jo.optJSONObject(PI_COVERINFO); if (cjo != null) { - mPendingCover = new PluginInfo(cjo); + setPendingCover(new PluginInfo(cjo)); } // 缓存"待覆盖安装"的插件覆盖字段 - mIsPendingCover = jo.optBoolean("cover"); + setIsPendingCover(jo.optBoolean(PI_COVER)); } // 通过别名和包名来最终确认插件名 @@ -259,7 +271,7 @@ public static PluginInfo parseFromJsonText(String joText) { } // 三个字段是必备的,其余均可 - if (jo.has("pkgname") && jo.has("type") && jo.has("ver")) { + if (jo.has(PI_PKGNAME) && jo.has(PI_TYPE) && jo.has(PI_VER)) { return new PluginInfo(jo); } else { return null; @@ -271,35 +283,35 @@ public static PluginInfo parseFromJsonText(String joText) { * (注意:旧插件"p-n"的"别名"就是插件名) */ public String getName() { - return mJson.optString("name"); + return get(PI_NAME, ""); } /** * 获取插件包名 */ public String getPackageName() { - return mJson.optString("pkgname"); + return get(PI_PKGNAME, ""); } /** * 获取插件别名 */ public String getAlias() { - return mJson.optString("ali"); + return get(PI_ALI, ""); } /** * 获取插件的版本 */ public int getVersion() { - return mJson.optInt("ver"); + return get(PI_VER, 0); } /** * 获取最新的插件,目前所在的位置 */ public String getPath() { - return mJson.optString("path"); + return get(PI_PATH, ""); } /** @@ -307,7 +319,7 @@ public String getPath() { * 注意:若为“纯APK”方案所用,则修改后需调用PluginInfoList.save来保存,否则会无效 */ public void setPath(String path) { - JSONHelper.putNoThrows(mJson, "path", path); + put(PI_PATH, path); } /** @@ -325,7 +337,7 @@ public boolean isUsed() { return getParentInfo().isUsed(); } else { // 若是纯APK,且不是PendingUpdate,则直接从Json中获取 - return mJson.optBoolean("used"); + return get(PI_USED, false); } } @@ -336,14 +348,14 @@ public boolean isUsed() { * @param used 插件是否被使用过 */ public void setIsUsed(boolean used) { - JSONHelper.putNoThrows(mJson, "used", used); + put(PI_USED, used); } /** * 获取Long型的,可用来对比的版本号 */ public long getVersionValue() { - return mJson.optLong("verv"); + return get(PI_VERV, 0L); } /** @@ -511,7 +523,7 @@ public File getNativeLibsDir() { * 获取插件当前所处的类型。详细见TYPE_XXX常量 */ public int getType() { - return mJson.optInt("type"); + return get(PI_TYPE, 0); } /** @@ -519,7 +531,7 @@ public int getType() { * 注意:若为“纯APK”方案所用,则修改后需调用PluginInfoList.save来保存,否则会无效 */ public void setType(int type) { - JSONHelper.putNoThrows(mJson, "type", type); + put(PI_TYPE, type); } /** @@ -549,9 +561,9 @@ public PluginInfo getPendingUpdate() { public void setPendingUpdate(PluginInfo info) { mPendingUpdate = info; if (info != null) { - JSONHelper.putNoThrows(mJson, "upinfo", info.getJSON()); + put(PI_UPINFO, info.getJSON()); } else { - mJson.remove("upinfo"); + mJson.remove(PI_UPINFO); } } @@ -582,9 +594,9 @@ public PluginInfo getPendingDelete() { public void setPendingDelete(PluginInfo info) { mPendingDelete = info; if (info != null) { - JSONHelper.putNoThrows(mJson, "delinfo", info.getJSON()); + put(PI_DELINFO, info.getJSON()); } else { - mJson.remove("delinfo"); + mJson.remove(PI_DELINFO); } } @@ -615,9 +627,9 @@ public PluginInfo getPendingCover() { public void setPendingCover(PluginInfo info) { mPendingCover = info; if (info != null) { - JSONHelper.putNoThrows(mJson, "coverinfo", info.getJSON()); + put(PI_COVERINFO, info.getJSON()); } else { - mJson.remove("coverinfo"); + mJson.remove(PI_COVERINFO); } } @@ -637,10 +649,10 @@ public boolean getIsPendingCover() { */ public void setIsPendingCover(boolean coverInfo) { mIsPendingCover = coverInfo; - if (mIsPendingCover) { - JSONHelper.putNoThrows(mJson, "cover", mIsPendingCover); + if (coverInfo) { + put(PI_COVER, true); } else { - mJson.remove("cover"); + mJson.remove(PI_COVER); } } @@ -648,7 +660,7 @@ public void setIsPendingCover(boolean coverInfo) { * 获取最小支持宿主API的版本 */ public int getLowInterfaceApi() { - return mJson.optInt("low", Constant.ADAPTER_COMPATIBLE_VERSION); + return get(PI_LOW, Constant.ADAPTER_COMPATIBLE_VERSION); } /** @@ -657,7 +669,7 @@ public int getLowInterfaceApi() { * @deprecated 可能会废弃 */ public int getHighInterfaceApi() { - return mJson.optInt("high", Constant.ADAPTER_COMPATIBLE_VERSION); + return get(PI_HIGH, Constant.ADAPTER_COMPATIBLE_VERSION); } /** @@ -667,7 +679,7 @@ public int getHighInterfaceApi() { public int getFrameworkVersion() { // 仅p-n插件在用 // 之所以默认为FRAMEWORK_VERSION_UNKNOWN,是因为在这里还只是读取p-n文件头,框架版本需要在loadDex阶段获得 - return mJson.optInt("frm_ver", FRAMEWORK_VERSION_UNKNOWN); + return get(PI_FRM_VER, FRAMEWORK_VERSION_UNKNOWN); } /** @@ -677,7 +689,7 @@ public int getFrameworkVersion() { * @param version 框架版本号 */ public void setFrameworkVersion(int version) { - JSONHelper.putNoThrows(mJson, "frm_ver", version); + put(PI_FRM_VER, version); } /** @@ -700,7 +712,7 @@ public void setFrameworkVersionByMeta(Bundle meta) { // @hide public JSONObject getJSON() { - return mJson; + return new JSONObject(mJson); } /** @@ -756,30 +768,30 @@ public void setParentInfo(PluginInfo parent) { } static PluginInfo createByJO(JSONObject jo) { + if (jo == null || jo.length() == 0) return null; PluginInfo pi = new PluginInfo(jo); // 必须有包名或别名 if (TextUtils.isEmpty(pi.getName())) { return null; } - return pi; } private void setPackageName(String pkgName) { if (!TextUtils.equals(pkgName, getPackageName())) { - JSONHelper.putNoThrows(mJson, "pkgname", pkgName); + put(PI_PKGNAME, pkgName); } } private void setAlias(String alias) { if (!TextUtils.equals(alias, getAlias())) { - JSONHelper.putNoThrows(mJson, "ali", alias); + put(PI_ALI, alias); } } private void setVersion(int version) { - JSONHelper.putNoThrows(mJson, "ver", version); - JSONHelper.putNoThrows(mJson, "verv", buildCompareValue()); + put(PI_VER, version); + put(PI_VERV, buildCompareValue()); } // ------------------------- @@ -816,50 +828,13 @@ private PluginInfo(Parcel source) { @Override public Object clone() { - PluginInfo pluginInfo = null; - - // 通过 transient 和 Serializable 配合实现深拷贝 - this.mJsonText = this.mJson != null ? this.mJson.toString() : null; - - // Object -> Stream -> clone Object try { - ByteArrayOutputStream byteArrOut = new ByteArrayOutputStream(); - ObjectOutputStream objOut = new ObjectOutputStream(byteArrOut); - - objOut.writeObject(this); - - ByteArrayInputStream byteArrIn = new ByteArrayInputStream(byteArrOut.toByteArray()); - ObjectInputStream objIn = new ObjectInputStream(byteArrIn); - - pluginInfo = (PluginInfo) objIn.readObject(); - - if (pluginInfo != null && !TextUtils.isEmpty(this.mJsonText)) { - pluginInfo.mJson = new JSONObject(this.mJsonText); - - JSONObject ujo = pluginInfo.mJson.optJSONObject("upinfo"); - if (ujo != null) { - pluginInfo.mPendingUpdate = new PluginInfo(ujo); - } - - JSONObject djo = pluginInfo.mJson.optJSONObject("delinfo"); - if (djo != null) { - pluginInfo.mPendingDelete = new PluginInfo(djo); - } - - JSONObject cjo = pluginInfo.mJson.optJSONObject("coverinfo"); - if (cjo != null) { - pluginInfo.mPendingCover = new PluginInfo(cjo); - } - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + final String jsonText = getJSON().toString(); + return new PluginInfo(new JSONObject(jsonText)); } catch (JSONException e) { e.printStackTrace(); } - - return pluginInfo; + return null; } @Override @@ -869,20 +844,16 @@ public int describeContents() { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mJson.toString()); + dest.writeString(getJSON().toString()); } @Override public String toString() { - synchronized (this) { - StringBuilder b = new StringBuilder(); - - b.append("PInfo { "); - toContentString(b); - b.append(" }"); - - return b.toString(); - } + final StringBuilder b = new StringBuilder(); + b.append("PInfo { "); + toContentString(b); + b.append(" }"); + return b.toString(); } private void toContentString(StringBuilder b) { @@ -972,7 +943,7 @@ public boolean equals(Object obj) { // ------------------------- public static final String QUERY_COLUMNS[] = { - "name", "low", "high", "ver", "type", "v5type", "path", "v5index", "v5offset", "v5length", "v5md5" + PI_NAME, PI_LOW, PI_HIGH, PI_VER, PI_TYPE, "v5type", PI_PATH, "v5index", "v5offset", "v5length", "v5md5" }; private static final Pattern REGEX; @@ -1033,17 +1004,17 @@ public static final PluginInfo build(File f) { public static final PluginInfo buildFromBuiltInJson(JSONObject jo) { String pkgName = jo.optString("pkg"); - String name = jo.optString("name"); - String assetName = jo.optString("path"); + String name = jo.optString(PI_NAME); + String assetName = jo.optString(PI_PATH); if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pkgName) || TextUtils.isEmpty(assetName)) { if (LogDebug.LOG) { LogDebug.d(TAG, "buildFromBuiltInJson: Invalid json. j=" + jo); } return null; } - int low = jo.optInt("low", Constant.ADAPTER_COMPATIBLE_VERSION); // Low应指向最低兼容版本 - int high = jo.optInt("high", Constant.ADAPTER_COMPATIBLE_VERSION); // High同上 - int ver = jo.optInt("ver"); + int low = jo.optInt(PI_LOW, Constant.ADAPTER_COMPATIBLE_VERSION); // Low应指向最低兼容版本 + int high = jo.optInt(PI_HIGH, Constant.ADAPTER_COMPATIBLE_VERSION); // High同上 + int ver = jo.optInt(PI_VER); PluginInfo info = new PluginInfo(pkgName, name, low, high, ver, assetName, TYPE_BUILTIN); // 从 json 中读取 frameVersion(可选) @@ -1083,11 +1054,11 @@ public static final PluginInfo build(String name, int low, int high, int ver) { private PluginInfo(String name, int low, int high, int ver, int type, int v5Type, String path, int v5index, int v5offset, int v5length, String v5md5) { this(name, name, low, high, ver, path, type); - JSONHelper.putNoThrows(mJson, "v5type", v5Type); - JSONHelper.putNoThrows(mJson, "v5index", v5index); - JSONHelper.putNoThrows(mJson, "v5offset", v5offset); - JSONHelper.putNoThrows(mJson, "v5length", v5length); - JSONHelper.putNoThrows(mJson, "v5md5", v5md5); + put("v5type", v5Type); + put("v5index", v5index); + put("v5offset", v5offset); + put("v5length", v5length); + put("v5md5", v5md5); } private String formatName() { @@ -1101,13 +1072,13 @@ final void to(MatrixCursor cursor) { } public final void to(Intent intent) { - intent.putExtra("name", getName()); - intent.putExtra("low", getLowInterfaceApi()); - intent.putExtra("high", getHighInterfaceApi()); - intent.putExtra("ver", getVersion()); - intent.putExtra("type", getType()); + intent.putExtra(PI_NAME, getName()); + intent.putExtra(PI_LOW, getLowInterfaceApi()); + intent.putExtra(PI_HIGH, getHighInterfaceApi()); + intent.putExtra(PI_VER, getVersion()); + intent.putExtra(PI_TYPE, getType()); intent.putExtra("v5type", getV5Type()); - intent.putExtra("path", getPath()); + intent.putExtra(PI_PATH, getPath()); intent.putExtra("v5index", getV5Index()); intent.putExtra("v5offset", getV5Offset()); intent.putExtra("v5length", getV5Length()); @@ -1190,7 +1161,7 @@ public boolean isPnPlugin() { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public int getV5Type() { - return mJson.optInt("v5type", V5FileInfo.NONE_PLUGIN); + return get("v5type", V5FileInfo.NONE_PLUGIN); } /** @@ -1199,7 +1170,7 @@ public int getV5Type() { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public int getV5Index() { - return mJson.optInt("v5index", -1); + return get("v5index", -1); } /** @@ -1208,7 +1179,7 @@ public int getV5Index() { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public int getV5Offset() { - return mJson.optInt("v5offset", -1); + return get("v5offset", -1); } /** @@ -1217,7 +1188,7 @@ public int getV5Offset() { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public int getV5Length() { - return mJson.optInt("v5length", -1); + return get("v5length", -1); } /** @@ -1226,7 +1197,19 @@ public int getV5Length() { * @deprecated 只用于旧的P-n插件,可能会废弃 */ public String getV5MD5() { - return mJson.optString("v5md5"); + return get("v5md5", ""); + } + + //// + + private T get(String name, @NonNull T def) { + final Object obj = mJson.get(name); + return (def.getClass().isInstance(obj)) ? (T) obj : def; + } + + public void put(String key, T value) { + if (key == null || value == null) return; + mJson.put(key, value); //value & key must not null } } diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java index 4a299bfc..a42a1c89 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java @@ -17,14 +17,14 @@ package com.qihoo360.replugin.model; import android.content.Context; +import android.support.annotation.NonNull; import android.text.TextUtils; import com.qihoo360.loader2.Constant; -import com.qihoo360.replugin.helper.JSONHelper; import com.qihoo360.replugin.helper.LogDebug; - import com.qihoo360.replugin.utils.Charsets; import com.qihoo360.replugin.utils.FileUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -32,6 +32,8 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -46,80 +48,27 @@ public class PluginInfoList implements Iterable { private final ConcurrentHashMap mMap = new ConcurrentHashMap<>(); - // FIXME 确认是否有必要 - private final List mList = new ArrayList<>(); - - private JSONArray mJson = new JSONArray(); - public void add(PluginInfo pi) { - if (get(pi.getName()) != null) { - // 已有?不能再加入 - return; - } - mJson.put(pi.getJSON()); - addToMap(pi); } - private void addToMap(PluginInfo pi) { - mMap.put(pi.getName(), pi); - mMap.put(pi.getAlias(), pi); - mList.add(pi); - } - public void remove(String pn) { - for (int i = 0; i < mJson.length(); i++) { - JSONObject jo = mJson.optJSONObject(i); - if (TextUtils.equals(pn, jo.optString("name"))) { - JSONHelper.remove(mJson, i); - } - } - if (mMap.containsKey(pn)) { - mMap.remove(pn); - } - removeListElement(mList, pn); - } - - private void removeListElement(List list, String pn) { - Iterator iterator = list.iterator(); - while(iterator.hasNext()) { - PluginInfo pluginInfo = iterator.next(); - if(TextUtils.equals(pn, pluginInfo.getName())) { - iterator.remove(); - } - } + mMap.remove(pn); } public PluginInfo get(String pn) { - return mMap.get(pn); + return pn != null ? mMap.get(pn) : null; } public List cloneList() { - return new ArrayList<>(mList); + return new ArrayList<>(getCopyValues()); } public boolean load(Context context) { - try { - // 1. 新建或打开文件 - File d = context.getDir(Constant.LOCAL_PLUGIN_APK_SUB_DIR, 0); - File f = new File(d, "p.l"); - if (!f.exists()) { - // 不存在?直接创建一个新的即可 - if (!f.createNewFile()) { - if (LogDebug.LOG) { - LogDebug.e(TAG, "load: Create error!"); - } - return false; - } else { - if (LogDebug.LOG) { - LogDebug.i(TAG, "load: Create a new list file"); - } - return true; - } - } - - // 2. 读出字符串 - String result = FileUtils.readFileToString(f, Charsets.UTF_8); + try { + // 1. 读出字符串 + final File f = getFile(context); + final String result = FileUtils.readFileToString(f, Charsets.UTF_8); if (TextUtils.isEmpty(result)) { if (LogDebug.LOG) { LogDebug.e(TAG, "load: Read Json error!"); @@ -127,25 +76,11 @@ public boolean load(Context context) { return false; } - // 3. 解析出JSON - mJson = new JSONArray(result); - - } catch (IOException e) { - if (LogDebug.LOG) { - LogDebug.e(TAG, "load: Load error!", e); - } - return false; - } catch (JSONException e) { - if (LogDebug.LOG) { - LogDebug.e(TAG, "load: Parse Json Error!", e); - } - return false; - } - - for (int i = 0; i < mJson.length(); i++) { - JSONObject jo = mJson.optJSONObject(i); - if (jo != null) { - PluginInfo pi = PluginInfo.createByJO(jo); + // 2. 解析出JSON + final JSONArray jArr = new JSONArray(result); + for (int i = 0; i < jArr.length(); i++) { + final JSONObject jo = jArr.optJSONObject(i); + final PluginInfo pi = PluginInfo.createByJO(jo); if (pi == null) { if (LogDebug.LOG) { LogDebug.e(TAG, "load: PluginInfo Invalid. Ignore! jo=" + jo); @@ -154,16 +89,25 @@ public boolean load(Context context) { } addToMap(pi); } + return true; + } catch (IOException e) { + if (LogDebug.LOG) { + LogDebug.e(TAG, "load: Load error!", e); + } + } catch (JSONException e) { + if (LogDebug.LOG) { + LogDebug.e(TAG, "load: Parse Json Error!", e); + } } - return true; + return false; } public boolean save(Context context) { try { - File d = context.getDir(Constant.LOCAL_PLUGIN_APK_SUB_DIR, 0); - File f = new File(d, "p.l"); - FileUtils.writeStringToFile(f, mJson.toString(), Charsets.UTF_8); - + final File f = getFile(context); + final JSONArray jsonArr = new JSONArray(); + for (PluginInfo i : getCopyValues()) jsonArr.put(i.getJSON()); + FileUtils.writeStringToFile(f, jsonArr.toString(), Charsets.UTF_8); return true; } catch (IOException e) { if (LogDebug.LOG) { @@ -175,6 +119,25 @@ public boolean save(Context context) { @Override public Iterator iterator() { - return mList.iterator(); + return getCopyValues().iterator(); + } + + /// + + @NonNull + private Collection getCopyValues() { + return new HashSet(mMap.values()); //是否有必要去重??? + } + + private void addToMap(PluginInfo pi) { + if (pi == null) return; + if (!TextUtils.isEmpty(pi.getName())) mMap.put(pi.getName(), pi); + if (!TextUtils.isEmpty(pi.getAlias())) mMap.put(pi.getAlias(), pi); + } + + @NonNull + private File getFile(Context context) { + final File d = context.getDir(Constant.LOCAL_PLUGIN_APK_SUB_DIR, 0); + return new File(d, "p.l"); } } diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/packages/PluginManagerServer.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/packages/PluginManagerServer.java index 4aa5cde4..bef0da22 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/packages/PluginManagerServer.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/packages/PluginManagerServer.java @@ -58,12 +58,6 @@ public class PluginManagerServer { private static final String TAG = "PluginManagerServer"; - /*** 非法类型的插件*/ - public static final int PLUGIN_TYPE_INVALID = 0; - /*** PN类型的插件*/ - public static final int PLUGIN_TYPE_PN = 1; - /*** APK类型的插件*/ - public static final int PLUGIN_TYPE_APK = 2; private static final byte[] LOCKER_PROCESS_KILLED = new byte[0]; private static final byte[] LOCKER = new byte[0]; @@ -164,7 +158,7 @@ private PluginInfo installLocked(String path) { if (checkResult < 0) { RePlugin.getConfig().getEventCallbacks().onInstallPluginFailed(path, RePluginEventCallbacks.InstallResult.VERIFY_VER_FAIL); return null; - } else if (checkResult == 0) { + } else if (checkResult == 0){ instPli.setIsPendingCover(true); } } @@ -210,7 +204,7 @@ private boolean verifySignature(PackageInfo pi, String path) { private int checkVersion(PluginInfo instPli, PluginInfo curPli) { // 支持插件同版本覆盖安装? // 若现在要安装的,与之前的版本相同,则覆盖掉之前的版本; - if (instPli.getVersion() == curPli.getVersion() && getPluginType(instPli) == getPluginType(curPli)) { + if (instPli.getVersion() == curPli.getVersion()) { if (LogDebug.LOG) { LogDebug.d(TAG, "isSameVersion: same version. " + "inst_ver=" + instPli.getVersion() + "; cur_ver=" + curPli.getVersion()); @@ -295,8 +289,7 @@ private void updateOrLater(PluginInfo curPli, PluginInfo instPli) { if (LogDebug.LOG) { LogDebug.w(TAG, "updateOrLater: Plugin is running. Later. pn=" + curPli.getName()); } - if (instPli.getVersion() > curPli.getVersion() || - instPli.getVersion() == curPli.getVersion() && getPluginType(instPli) != getPluginType(curPli)) { + if (instPli.getVersion() > curPli.getVersion()) { // 高版本升级 curPli.setPendingUpdate(instPli); curPli.setPendingDelete(null); @@ -304,7 +297,7 @@ private void updateOrLater(PluginInfo curPli, PluginInfo instPli) { if (LogDebug.LOG) { LogDebug.w(TAG, "updateOrLater: Plugin need update high version. clear PendingDelete and PendingCover."); } - } else if (instPli.getVersion() == curPli.getVersion()) { + } else if (instPli.getVersion() == curPli.getVersion()){ // 同版本覆盖 curPli.setPendingCover(instPli); curPli.setPendingDelete(null); @@ -324,10 +317,6 @@ private void updateOrLater(PluginInfo curPli, PluginInfo instPli) { } } - private static int getPluginType(PluginInfo pluginInfo) { - return pluginInfo == null ? PLUGIN_TYPE_INVALID : pluginInfo.isPnPlugin() ? PLUGIN_TYPE_PN : PLUGIN_TYPE_APK; - } - private void updatePendingUpdate(PluginInfo curPli, PluginInfo instPli, PluginInfo curUpdatePli) { if (curUpdatePli.getVersion() < instPli.getVersion()) { // 现在的版本比之前"打算要更新"的版本还要新(形象的称之为“夹心层”),则删除掉该“夹心层”的版本,然后换成这个更新的 @@ -339,6 +328,7 @@ private void updatePendingUpdate(PluginInfo curPli, PluginInfo instPli, PluginIn // 设置待更新版本至最大版本 curPli.setPendingUpdate(instPli); + instPli.setParentInfo(curPli); // 删除“夹心层”插件文件 try { @@ -604,7 +594,7 @@ private void addToRunningPluginsLocked(String processName, int pid, String plugi l.add(pluginName); if (LogDebug.LOG) { - LogDebug.d(TAG, "addToRunningPluginsLocked: Added! pl =" + l + "; map=" + mProcess2PluginsMap); + LogDebug.d(TAG, "addToRunningPluginsLocked: Added! pl =" + l +"; map=" + mProcess2PluginsMap); } } diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/utils/FileUtils.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/utils/FileUtils.java index 086fc212..66bbaa72 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/utils/FileUtils.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/utils/FileUtils.java @@ -736,4 +736,23 @@ public static String getFileNameWithoutExt(String filePath) { return (filePosition < extensionPosition ? filePath.substring(filePosition + 1, extensionPosition) : filePath.substring(filePosition + 1)); } + + /** + * 根据输入的文件路径,得到扩展名 + * + * @param filePath + * @return + */ + public static String getFileExt(String filePath) { + if (TextUtils.isEmpty(filePath)) { + return filePath; + } + + int extPosi = filePath.lastIndexOf("."); + int filePosi = filePath.lastIndexOf(File.separator); + if (extPosi == -1) { + return ""; + } + return (filePosi >= extPosi) ? "" : filePath.substring(extPosi + 1); + } } \ No newline at end of file diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderExprEditor.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderExprEditor.groovy index 9082c020..fab22e42 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderExprEditor.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderExprEditor.groovy @@ -32,15 +32,18 @@ public class ProviderExprEditor extends ExprEditor { @Override void edit(MethodCall m) throws CannotCompileException { - String clsName = m.getClassName() - String methodName = m.getMethodName() - - if (clsName.equalsIgnoreCase('android.content.ContentResolver')) { - if (!(methodName in ProviderInjector.includeMethodCall)) { - // println "跳过$methodName" - return - } + final String clsName = m.getClassName() + final String methodName = m.getMethodName() + if (!clsName.equalsIgnoreCase('android.content.ContentResolver')) { + return + } + if (!(methodName in ProviderInjector.includeMethodCall)) { // println "跳过$methodName" + return + } + try { replaceStatement(m, methodName, m.lineNumber) + } catch (Exception e) { //确保不影响其他 MethodCall + println " [Warning] --> ProviderExprEditor : ${e.toString()}" } } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy index c853ef49..aed10d6b 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy @@ -36,12 +36,14 @@ public class ProviderInjector extends BaseInjector { 'bulkInsert', 'delete', 'update', - 'openInputStream', - 'openOutputStream', - 'openFileDescriptor', - 'registerContentObserver', - 'acquireContentProviderClient', - 'notifyChange', + /// 以下方法 replugin plugin lib 暂未支持,导致字节码修改失败。 +// 'openInputStream', +// 'openOutputStream', +// 'openFileDescriptor', +// 'registerContentObserver', +// 'acquireContentProviderClient', +// 'notifyChange', +// 'toCalledUri', ] // 表达式编辑器 @@ -86,11 +88,8 @@ public class ProviderInjector extends BaseInjector { } editor.filePath = filePath - ctCls.getDeclaredMethods().each { - it.instrument(editor) - } - ctCls.getMethods().each { + (ctCls.getDeclaredMethods() + ctCls.getMethods()).each { it.instrument(editor) } diff --git a/replugin-plugin-library/replugin-plugin-lib/src/main/java/com/qihoo360/replugin/loader/p/PluginProviderClient.java b/replugin-plugin-library/replugin-plugin-lib/src/main/java/com/qihoo360/replugin/loader/p/PluginProviderClient.java index 2453fc4b..51c8915a 100644 --- a/replugin-plugin-library/replugin-plugin-lib/src/main/java/com/qihoo360/replugin/loader/p/PluginProviderClient.java +++ b/replugin-plugin-library/replugin-plugin-lib/src/main/java/com/qihoo360/replugin/loader/p/PluginProviderClient.java @@ -19,6 +19,7 @@ import android.annotation.TargetApi; import android.content.ContentValues; import android.content.Context; +import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Build; @@ -196,6 +197,34 @@ public static int update(Context c, Uri uri, ContentValues values, String select return -1; } + /** + * 调用插件里的Provider + * + * @see android.content.ContentResolver#getType(Uri) + */ + public static String getType(Context c, Uri uri) { + if (c == null) { + return null; + } + + if (!RePluginFramework.mHostInitialized) { + return c.getContentResolver().getType(uri); + } + + try { + Object obj = ProxyRePluginProviderClientVar.getType.call(null, c, uri); + if (obj != null) { + return (String) obj; + } + } catch (Exception e) { + if (LogDebug.LOG) { + e.printStackTrace(); + } + } + + return null; + } + public static class ProxyRePluginProviderClientVar { private static MethodInvoker query; @@ -210,6 +239,30 @@ public static class ProxyRePluginProviderClientVar { private static MethodInvoker update; + private static MethodInvoker getType; + + private static MethodInvoker openInputStream; + + private static MethodInvoker openOutputStream; + + private static MethodInvoker openOutputStream2; + + private static MethodInvoker openFileDescriptor; + + private static MethodInvoker openFileDescriptor2; + + private static MethodInvoker registerContentObserver; + + private static MethodInvoker acquireContentProviderClient; + + private static MethodInvoker notifyChange; + + private static MethodInvoker notifyChange2; + + private static MethodInvoker toCalledUri; + + private static MethodInvoker toCalledUri2; + public static void initLocked(final ClassLoader classLoader) { // String rePluginProviderClient = "com.qihoo360.loader2.mgr.PluginProviderClient"; @@ -223,6 +276,21 @@ public static void initLocked(final ClassLoader classLoader) { bulkInsert = new MethodInvoker(classLoader, rePluginProviderClient, "bulkInsert", new Class[]{Context.class, Uri.class, ContentValues[].class}); delete = new MethodInvoker(classLoader, rePluginProviderClient, "delete", new Class[]{Context.class, Uri.class, String.class, String[].class}); update = new MethodInvoker(classLoader, rePluginProviderClient, "update", new Class[]{Context.class, Uri.class, ContentValues.class, String.class, String[].class}); + // new supported + getType = new MethodInvoker(classLoader, rePluginProviderClient, "getType", new Class[]{Context.class, Uri.class}); + openInputStream = new MethodInvoker(classLoader, rePluginProviderClient, "openInputStream", new Class[]{Context.class, Uri.class}); + openOutputStream = new MethodInvoker(classLoader, rePluginProviderClient, "openOutputStream", new Class[]{Context.class, Uri.class}); + openOutputStream2 = new MethodInvoker(classLoader, rePluginProviderClient, "openOutputStream", new Class[]{Context.class, Uri.class, String.class}); + openFileDescriptor = new MethodInvoker(classLoader, rePluginProviderClient, "openFileDescriptor", new Class[]{Context.class, Uri.class, String.class}); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + openFileDescriptor2 = new MethodInvoker(classLoader, rePluginProviderClient, "openFileDescriptor", new Class[]{Context.class, Uri.class, String.class, CancellationSignal.class}); + } + registerContentObserver = new MethodInvoker(classLoader, rePluginProviderClient, "registerContentObserver", new Class[]{Context.class, Uri.class, Boolean.class, ContentObserver.class}); + acquireContentProviderClient = new MethodInvoker(classLoader, rePluginProviderClient, "acquireContentProviderClient", new Class[]{Context.class, String.class}); + notifyChange = new MethodInvoker(classLoader, rePluginProviderClient, "notifyChange", new Class[]{Context.class, Uri.class, ContentObserver.class}); + notifyChange2 = new MethodInvoker(classLoader, rePluginProviderClient, "notifyChange", new Class[]{Context.class, Uri.class, ContentObserver.class, Boolean.class}); + toCalledUri = new MethodInvoker(classLoader, rePluginProviderClient, "toCalledUri", new Class[]{Context.class, Uri.class}); + toCalledUri2 = new MethodInvoker(classLoader, rePluginProviderClient, "toCalledUri", new Class[]{Context.class, String.class, Uri.class, Integer.class}); } } } diff --git a/rp-config.gradle b/rp-config.gradle index 39e7e57f..7b9ac0c6 100644 --- a/rp-config.gradle +++ b/rp-config.gradle @@ -10,5 +10,5 @@ project.ext{ RP_LICENSES_NAME = 'Apache-2.0' // RP_GROUP = 'com.qihoo360.replugin' - RP_VERSION = '2.3.1' + RP_VERSION = '2.3.2' } \ No newline at end of file diff --git a/rp-publish.gradle b/rp-publish.gradle index 6cff4872..8b05af1c 100644 --- a/rp-publish.gradle +++ b/rp-publish.gradle @@ -183,12 +183,12 @@ if ( pbBintayKey == null ){ /////// publish to LOCAL // apply plugin: 'maven' - -// uploadArchives { -// repositories.mavenDeployer { -// repository(url: "file://${System.getenv('HOME')}/.m2") -// pom.groupId = group -// pom.version = version -// pom.artifactId = pbArtifactId -// } -// } \ No newline at end of file +//final def theGroup = group // group will be reset to 'upload' +//uploadArchives { +// repositories.mavenDeployer { +// repository(url: "file://${System.getenv('HOME')}/.m2/repository") +// pom.groupId = theGroup +// pom.version = version +// pom.artifactId = pbArtifactId +// } +//} \ No newline at end of file