Merge pull request #175 from jiongxuan/master

Fix and optimize "host-lib"
This commit is contained in:
王玉鹏 2017-07-10 21:18:19 +08:00 committed by GitHub
commit 2c64f5f735
13 changed files with 195 additions and 485 deletions

View File

@ -36,17 +36,12 @@ android {
consumerProguardFiles 'replugin-rules.pro'
}
buildTypes {
release {
minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'replugin-rules.pro'
}
}
lintOptions {
abortOnError false
}
// Debug版AAR便
defaultPublishConfig "debug"
}

View File

@ -1,95 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ./sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# ——————————————————————————————————————
# 构建 aar 时的混淆规则
# 即:此处 keep 的内容可以被宿主调用,但是宿主的 Release 包中,以下内容'可能'无法访问
# ——————————————————————————————————————————————————————————————————————————————
# -keepattributes SourceFile,LineNumberTable
-keepattributes LineNumberTable
-keep class com.qihoo360.replugin.** { public protected *;}
# 架构具体实现,和插件反射调用部分
-keep class com.qihoo360.replugin.model.PluginInfo {
public protected *;
}
-keep class com.qihoo360.replugin.component.ComponentList {
public protected *;
}
-keep class com.qihoo360.framework.** {
public protected *;
}
-keep class com.qihoo360.i.** {
public protected *;
}
-keep class com.qihoo360.plugins.** {
public protected *;
}
-keep class com.qihoo360.plugin.** {
public protected *;
}
-keep class com.qihoo360.replugin.component.dummy.** {
public protected *;
}
-keep class com.qihoo360.replugin.component.provider.PluginProviderClient {
public protected *;
}
-keep class com.qihoo360.replugin.component.service.PluginServiceClient {
public protected *;
}
-keep class com.qihoo360.i.IModule { public *;}
-keep class com.qihoo360.i.Factory2 { public *;}
-keep class com.qihoo360.i.IPluginManager { public *;}
-keep class com.qihoo360.loader.utils.SysUtils { public *;}
-keep class com.qihoo360.loader.utils.StringUtils { public *;}
-keep class com.qihoo360.loader.utils.ReflectUtils { public *;}
-keep class com.qihoo360.loader2.MP { public *;}
-keep class com.qihoo360.loader2.PMF { public *;}
-keep class com.qihoo360.loader2.PmBase { public *;}
-keep class com.qihoo360.loader2.sp.IPref { public *;}
-keep class com.qihoo360.loader2.CertUtils { public *;}
-keep class com.qihoo360.loader2.V5FileInfo { public *;}
-keep class com.qihoo360.loader2.PluginDesc { public *;}
-keep class com.qihoo360.loader2.PmLocalImpl { public *;}
-keep class com.qihoo360.loader2.sp.PrefImpl { public *;}
-keep class com.qihoo360.loader2.BinderCursor { public *;}
-keep class com.qihoo360.loader2.PluginManager { public *;}
-keep class com.qihoo360.loader2.MP$PluginBinder { public *;}
-keep class com.qihoo360.loader2.PluginProviderStub { public * ;}
-keep class com.qihoo360.replugin.component.provider.PluginPitProviderUI { public *;}
-keep class com.qihoo360.loader2.PluginStatusController { public *;}
-keep class com.qihoo360.replugin.component.utils.PluginClientHelper { public * ;}
-keep class com.qihoo360.replugin.component.provider.PluginPitProviderPersist { public *;}
-keep class com.qihoo360.loader2.ActivityLifecycleCallbacks { public *;}
-keep class com.qihoo360.replugin.component.app.PluginApplicationClient { public * ;}
-keep class com.qihoo360.replugin.component.activity.DynamicClassProxyActivity { public *;}
-keep class com.qihoo360.mobilesafe.api.IPC { public *;}
-keep class com.qihoo360.mobilesafe.api.Pref { public *;}
-keep class com.qihoo360.mobilesafe.api.Tasks { public *;}
-keep class com.qihoo360.mobilesafe.api.Intents { public *;}
-keep class com.qihoo360.loader2.PluginOverride { public *;}
-keep class com.qihoo360.replugin.component.process.ProcessPitProviderPersist { public * ;}
-keep class com.qihoo360.replugin.component.process.ProcessPitProviderBase { public * ;}

View File

@ -158,9 +158,11 @@ public class PluginDesc {
in = null;
try {
in = RePlugin.getConfig().getCallbacks().openLatestFile(context, "plugins-list.json");
String str = IOUtils.toString(in, Charsets.UTF_8);
return new JSONArray(str);
} catch (Throwable e) {
if (in != null) {
String str = IOUtils.toString(in, Charsets.UTF_8);
return new JSONArray(str);
}
} catch (Exception e) {
if (DEBUG) {
Log.e(TAG, e.getMessage(), e);
}

View File

@ -135,7 +135,7 @@ class PluginProcessPer extends IPluginClient.Stub {
@Override
public String allocActivityContainer(String plugin, int process, String target, Intent intent) throws RemoteException {
// 一旦有分配则进入监控状态一是避免不退出的情况二也是最重要的是避免现在就退出的情况
RePlugin.getConfig().getCallbacks().onPrepareAllocPitActivity(intent);
RePlugin.getConfig().getEventCallbacks().onPrepareAllocPitActivity(intent);
String loadPlugin = null;
// 如果UI进程启用尝试使用传过来的插件强制用UI进程
@ -214,7 +214,7 @@ class PluginProcessPer extends IPluginClient.Stub {
LogDebug.d(PLUGIN_TAG, "PluginImpl.releaseBinder");
}
// 告诉外界Binder已经被释放
RePlugin.getConfig().getCallbacks().onBinderReleased();
RePlugin.getConfig().getEventCallbacks().onBinderReleased();
}
@Override

View File

@ -262,7 +262,7 @@ class PmInternalImpl implements IPluginActivityManager {
// 通知外界已准备好要打开Activity了
// 其中from为要打开的插件的Intentto为坑位Intent
RePlugin.getConfig().getCallbacks().onPrepareStartPitActivity(context, from, intent);
RePlugin.getConfig().getEventCallbacks().onPrepareStartPitActivity(context, from, intent);
return true;
}
@ -549,7 +549,7 @@ class PmInternalImpl implements IPluginActivityManager {
}
// 触发退出检测
RePlugin.getConfig().getCallbacks().onActivityDestroyed(activity);
RePlugin.getConfig().getEventCallbacks().onActivityDestroyed(activity);
}
@Override

View File

@ -1,139 +1,20 @@
/*
* Copyright (C) 2005-2017 Qihoo 360 Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.qihoo360.replugin;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.qihoo360.mobilesafe.utils.pkg.PackageFilesUtil;
import com.qihoo360.replugin.model.PluginInfo;
import java.io.InputStream;
/**
* 插件框架对外回调接口集其中有一套默认的实现宿主可直接继承此类并复写要自定义的接口来修改插件化框架的逻辑
* <p>
* 注意可以只使用默认的Callbacks但默认实现不支持插件的下载下载部分需要实现自己的一套逻辑
* <p>
* 要了解每个接口的用途请参见PluginCallbacks接口的说明
*
* @author RePlugin Team
* @deprecated Use RePluginCallbacks instead
* @see RePluginCallbacks
* @author RePlugin Team
*/
public class DefaultRePluginCallbacks implements RePluginCallbacks {
private final Context mContext;
public class DefaultRePluginCallbacks extends RePluginCallbacks {
/**
* @deprecated Use RePluginCallbacks instead
* @see RePluginCallbacks#RePluginCallbacks(Context)
*/
public DefaultRePluginCallbacks(Context context) {
mContext = context;
super(context);
}
/**
* @see RePluginCallbacks#createClassLoader(ClassLoader, ClassLoader)
*/
@Override
public RePluginClassLoader createClassLoader(ClassLoader parent, ClassLoader original) {
return new RePluginClassLoader(parent, original);
}
/**
* @see RePluginCallbacks#createPluginClassLoader(String, String, String, ClassLoader)
*/
@Override
public PluginDexClassLoader createPluginClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) {
return new PluginDexClassLoader(dexPath, optimizedDirectory, librarySearchPath, parent);
}
/**
* @see RePluginCallbacks#onPluginNotExistsForActivity(Context, String, Intent, int)
*/
@Override
public boolean onPluginNotExistsForActivity(Context context, String plugin, Intent intent, int process) {
// Nothing
return false;
}
/**
* @see RePluginCallbacks#onLoadLargePluginForActivity(Context, String, Intent, int)
*/
@Override
public boolean onLoadLargePluginForActivity(Context context, String plugin, Intent intent, int process) {
// Nothing
return false;
}
/**
* @see RePluginCallbacks#onPrepareAllocPitActivity(Intent)
*/
@Override
public void onPrepareAllocPitActivity(Intent intent) {
// Nothing
}
/**
* @see RePluginCallbacks#onPrepareStartPitActivity(Context, Intent, Intent)
*/
@Override
public void onPrepareStartPitActivity(Context context, Intent intent, Intent pittedIntent) {
// Nothing
}
/**
* @see RePluginCallbacks#onActivityDestroyed(Activity)
*/
@Override
public void onActivityDestroyed(Activity activity) {
// Nothing
}
/**
* @see RePluginCallbacks#onBinderReleased()
*/
@Override
public void onBinderReleased() {
// Nothing
}
/**
* @see RePluginCallbacks#getSharedPreferences(Context, String, int)
*/
@Override
public SharedPreferences getSharedPreferences(Context context, String name, int mode) {
return context.getSharedPreferences(name, mode);
}
/**
* @see RePluginCallbacks#openLatestFile(Context, String)
*/
@Override
public InputStream openLatestFile(Context context, String filename) {
return PackageFilesUtil.openLatestInputFile(context, filename);
}
@Override
public ContextInjector createContextInjector() {
return null;
}
@Override
public boolean isPluginBlocked(PluginInfo pluginInfo) {
return false;
}
}

View File

@ -1,54 +1,20 @@
/*
* Copyright (C) 2005-2017 Qihoo 360 Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.qihoo360.replugin;
import android.content.Context;
import com.qihoo360.replugin.model.PluginInfo;
/**
* 插件化框架对外事件回调接口集
*
* 插件框架对外事件回调接口集其中有一套默认的实现宿主可直接继承此类并复写要自定义的接口来自定义插件化框架的事件逻辑
* <p>
* 要了解每个接口的用途请参见RePluginEventCallbacks接口的说明
*
* @deprecated Use RePluginEventCallbacks instead
* @see RePluginEventCallbacks
* @author RePlugin Team
*/
public class DefaultRePluginEventCallbacks implements RePluginEventCallbacks {
private final Context mContext;
public class DefaultRePluginEventCallbacks extends RePluginEventCallbacks {
/**
* @deprecated Use RePluginEventCallbacks instead
* @see RePluginEventCallbacks#RePluginEventCallbacks(Context)
*/
public DefaultRePluginEventCallbacks(Context context) {
mContext = context;
}
@Override
public void onInstallPluginFailed(String path, InstallResult code) {
}
@Override
public void onInstallPluginSucceed(PluginInfo info) {
}
@Override
public void onStartActivityCompleted(String plugin, String activity, boolean result) {
super(context);
}
}

View File

@ -16,12 +16,12 @@
package com.qihoo360.replugin;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.qihoo360.loader2.PluginContext;
import com.qihoo360.mobilesafe.utils.pkg.PackageFilesUtil;
import com.qihoo360.replugin.model.PluginInfo;
import java.io.InputStream;
@ -30,13 +30,16 @@ import java.io.InputStream;
* 插件框架对外回调接口集
* <p>
* 宿主需继承DefaultPluginCallbacks并复写相应的方法来自定义插件框架
* <p>
* 因为经常添加相应方法故请不要直接实现此接口
*
* @author RePlugin Team
* @see DefaultRePluginCallbacks
*/
public interface RePluginCallbacks {
public class RePluginCallbacks {
protected final Context mContext;
public RePluginCallbacks(Context context) {
mContext = context;
}
/**
* 创建宿主用的 RePluginClassLoader 对象以支持大多数插件化特征默认为RePluginClassLoader的实例
@ -48,7 +51,9 @@ public interface RePluginCallbacks {
* @return 支持插件化方案的ClassLoader对象可直接返回RePluginClassLoader
* @see RePluginClassLoader
*/
RePluginClassLoader createClassLoader(ClassLoader parent, ClassLoader original);
public RePluginClassLoader createClassLoader(ClassLoader parent, ClassLoader original) {
return new RePluginClassLoader(parent, original);
}
/**
* 插件插件用的 ClassLoader对象默认为PluginDexClassLoader的实例
@ -66,7 +71,9 @@ public interface RePluginCallbacks {
* @param parent 插件ClassLoader的父亲
* @return 插件自己可用的PluginDexClassLoader对象
*/
PluginDexClassLoader createPluginClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent);
public PluginDexClassLoader createPluginClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) {
return new PluginDexClassLoader(dexPath, optimizedDirectory, librarySearchPath, parent);
}
/**
* 当要打开的Activity所对应的插件不存在时触发通常在这里会触发下载逻辑
@ -78,7 +85,10 @@ public interface RePluginCallbacks {
* @param intent 要打开的Activity的Intent信息
* @param process 要打开的Activity所在进程
*/
boolean onPluginNotExistsForActivity(Context context, String plugin, Intent intent, int process);
public boolean onPluginNotExistsForActivity(Context context, String plugin, Intent intent, int process) {
// Nothing
return false;
}
/**
* 当要打开的Activity所对应的插件过大需要弹Loading窗提示时触发
@ -90,35 +100,10 @@ public interface RePluginCallbacks {
* @param intent 要打开的Activity的Intent信息
* @param process 要打开的Activity所在进程
*/
boolean onLoadLargePluginForActivity(Context context, String plugin, Intent intent, int process);
/**
* 当插件Activity准备分配坑位时执行
*
* @param intent 要打开的插件的Activity
*/
void onPrepareAllocPitActivity(Intent intent);
/**
* 当插件Activity即将被打开时执行在onActivityPitAllocated之后被执行
*
* @param context 要打开的Activity所在的Context
* @param intent 原来要打开的插件的Activity
* @param pittedIntent 目标坑位的Activity
*/
void onPrepareStartPitActivity(Context context, Intent intent, Intent pittedIntent);
/**
* 当插件Activity所在的坑位被执行销毁时被执行
*
* @param activity 要销毁的Activity对象通常是插件里的Activity
*/
void onActivityDestroyed(Activity activity);
/**
* 当插件Service的Binder被释放时被执行
*/
void onBinderReleased();
public boolean onLoadLargePluginForActivity(Context context, String plugin, Intent intent, int process) {
// Nothing
return false;
}
/**
* 获取SharedPreferences对象
@ -133,7 +118,9 @@ public interface RePluginCallbacks {
* @return The single {@link SharedPreferences} instance that can be used
* to retrieve and modify the preference values.
*/
SharedPreferences getSharedPreferences(Context context, String name, int mode);
public SharedPreferences getSharedPreferences(Context context, String name, int mode) {
return context.getSharedPreferences(name, mode);
}
/**
* 打开一个可被云控的插件框架方面的文件如plugin-list.json等
@ -149,7 +136,9 @@ public interface RePluginCallbacks {
* @param filename 要打开的文件名
* @return InputStream对象
*/
InputStream openLatestFile(Context context, String filename);
public InputStream openLatestFile(Context context, String filename) {
return PackageFilesUtil.openLatestInputFile(context, filename);
}
/**
* 获取业务层定义的ContextInjector实现对象允许业务层对PluginContext中的startActivity等接口处进行自定义操作
@ -160,13 +149,20 @@ public interface RePluginCallbacks {
*
* @since 2.0.0
*/
ContextInjector createContextInjector();
public ContextInjector createContextInjector() {
// Nothing
return null;
}
/**
* 判断当前插件是否已经处于禁用状态允许业务层自定义该禁用逻辑
*
* @param pluginInfo
* @return
* @param pluginInfo 插件的信息
* @return 是否被禁用
* @since 2.1.0
*/
boolean isPluginBlocked(PluginInfo pluginInfo);
public boolean isPluginBlocked(PluginInfo pluginInfo) {
// Nothing, allow all
return false;
}
}

View File

@ -40,15 +40,13 @@ public final class RePluginConfig {
private RePluginEventCallbacks eventCallbacks;
private File pnInstallDir;
private boolean verifySign = true;
private boolean verifySign = false;
private boolean persistentEnable = true;
private String persistentName = RePluginConstants.PERSISTENT_NAME_DEFAULT;
private boolean useHostClassIfNotFound = false;
private boolean moveFileWhenInstalling = true;
private boolean printDetailLog = false;
private int defaultFrameworkVersion = 4;
private String appID;
private String channel;
/**
* 获取插件回调方法通常无需调用此方法
@ -130,8 +128,9 @@ public final class RePluginConfig {
}
/**
* 设置插件是否开启签名校验 <p>
* 注意该功能仅针对纯APK插件p-n插件已默认开启了签名校验
* 设置插件是否开启签名校验默认为False但强烈建议开启此开关 <p>
* 此开关将必须和 RePlugin.addCertSignature 配合使用<p>
* 注意该功能仅针对纯APK插件
*
* @param verifySign
* @return RePluginConfig自己这样可以连环调用set方法
@ -297,56 +296,6 @@ public final class RePluginConfig {
return this;
}
/**
* 获取 AppID
*
* @return AppID
* @since 1.3.6
*/
public String getAppID() {
return appID;
}
/**
* 设置 AppID
*
* @param appId AppID
* @return RePluginConfig自己这样可以连环调用set方法
* @since 1.3.6
*/
public RePluginConfig setAppID(String appID) {
if (!checkAllowModify()) {
return this;
}
this.appID = appID;
return this;
}
/**
* 获取Channel渠道信息
*
* @return Channel
* @since 1.3.6
*/
public String getChannel() {
return channel;
}
/**
* 设置Channel渠道信息
*
* @param channel Channel
* @return RePluginConfig自己这样可以连环调用set方法
* @since 1.3.6
*/
public RePluginConfig setChannel(String channel) {
if (!checkAllowModify()) {
return this;
}
this.channel = channel;
return this;
}
// 针对RePlugin.App.AttachBaseContext的调用初始化默认值
void initDefaults(Context context) {
if (pnInstallDir == null) {
@ -354,11 +303,11 @@ public final class RePluginConfig {
}
if (callbacks == null) {
callbacks = new DefaultRePluginCallbacks(context);
callbacks = new RePluginCallbacks(context);
}
if (eventCallbacks == null) {
eventCallbacks = new DefaultRePluginEventCallbacks(context);
eventCallbacks = new RePluginEventCallbacks(context);
}
}

View File

@ -16,19 +16,26 @@
package com.qihoo360.replugin;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import com.qihoo360.replugin.model.PluginInfo;
/**
* 插件化框架对外事件回调接口集
* <p>
* 宿主需继承DefaultRePluginEventCallbacks并复写相应的方法来自定义插件框架
* <p>
* 因为经常添加相应方法故请不要直接实现此接口
* 宿主需继承此类并复写相应的方法来自定义插件框架的事件处理机制
*
* @author RePlugin Team
* @see DefaultRePluginEventCallbacks
*/
public interface RePluginEventCallbacks {
public class RePluginEventCallbacks {
protected final Context mContext;
public RePluginEventCallbacks(Context context) {
mContext = context;
}
/**
* 安装插件失败
@ -36,14 +43,18 @@ public interface RePluginEventCallbacks {
* @param path 插件路径
* @param code 安装失败的原因
*/
void onInstallPluginFailed(String path, InstallResult code);
public void onInstallPluginFailed(String path, InstallResult code) {
// Nothing
}
/**
* 安装插件成功
*
* @param info 插件信息
*/
void onInstallPluginSucceed(PluginInfo info);
public void onInstallPluginSucceed(PluginInfo info) {
// Nothing
}
/**
* 启动 Activity 完成
@ -52,12 +63,50 @@ public interface RePluginEventCallbacks {
* @param activity 插件 Activity
* @param result 启动是否成功
*/
void onStartActivityCompleted(String plugin, String activity, boolean result);
public void onStartActivityCompleted(String plugin, String activity, boolean result) {
// Nothing
}
/**
* 当插件Activity准备分配坑位时执行
*
* @param intent 要打开的插件的Activity
*/
public void onPrepareAllocPitActivity(Intent intent) {
// Nothing
}
/**
* 当插件Activity即将被打开时执行在onActivityPitAllocated之后被执行
*
* @param context 要打开的Activity所在的Context
* @param intent 原来要打开的插件的Activity
* @param pittedIntent 目标坑位的Activity
*/
public void onPrepareStartPitActivity(Context context, Intent intent, Intent pittedIntent) {
// Nothing
}
/**
* 当插件Activity所在的坑位被执行销毁时被执行
*
* @param activity 要销毁的Activity对象通常是插件里的Activity
*/
public void onActivityDestroyed(Activity activity) {
// Nothing
}
/**
* 当插件Service的Binder被释放时被执行
*/
public void onBinderReleased() {
// Nothing
}
/**
* 插件安装结果值
*/
enum InstallResult {
public enum InstallResult {
SUCCEED,
V5_FILE_BUILD_FAIL,
V5_FILE_UPDATE_FAIL,

View File

@ -65,12 +65,9 @@ public class ActivityInjector {
if (cl == null) {
return false;
}
ActivityInfo ai = cl.getActivity(realActivity);
if (ai == null) {
return false;
}
return inject(activity, ai, pi.getFrameworkVersion());
ActivityInfo ai = cl.getActivity(realActivity);
return ai != null && inject(activity, ai, pi.getFrameworkVersion());
}
private static boolean inject(Activity activity, ActivityInfo ai, int frameworkVer) {
@ -131,39 +128,15 @@ public class ActivityInjector {
* 获取 activity label 属性
*/
private static String getLabel(Activity activity, ActivityInfo ai) {
String label = "";
String label;
Resources res = activity.getResources();
// 获取 Activity label如有
if (ai.labelRes != 0) {
try {
label = res.getString(ai.labelRes);
if (LOG) {
LogDebug.d(TAG, "ai.label = " + label);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 ai.label 失败");
}
e.printStackTrace();
}
}
label = getLabelById(res, ai.labelRes);
// 获取插件 Application Label如有
if (TextUtils.isEmpty(label)) {
if (ai.applicationInfo.labelRes != 0) {
try {
label = res.getString(ai.applicationInfo.labelRes);
if (LOG) {
LogDebug.d(TAG, "ai.application.label = " + label);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 ai.application.label 失败");
}
e.printStackTrace();
}
}
label = getLabelById(res, ai.applicationInfo.labelRes);
}
// 获取宿主 App label
@ -171,20 +144,7 @@ public class ActivityInjector {
Context appContext = RePluginInternal.getAppContext();
Resources appResource = appContext.getResources();
ApplicationInfo appInfo = appContext.getApplicationInfo();
if (appInfo.labelRes != 0) {
try {
label = appResource.getString(appInfo.labelRes);
if (LOG) {
LogDebug.d(TAG, "host.application.label = " + label);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 host.application.label 失败");
}
e.printStackTrace();
}
}
label = getLabelById(appResource, appInfo.labelRes);
}
if (LOG) {
@ -193,57 +153,39 @@ public class ActivityInjector {
return label;
}
private static String getLabelById(Resources res, int id) {
if (id == 0) {
return null;
}
try {
return res.getString(id);
} catch (Resources.NotFoundException e) {
e.printStackTrace();
return null;
}
}
/**
* 获取 activity label 属性
* 获取 activity icon 属性
*/
private static Bitmap getIcon(Activity activity, ActivityInfo ai) {
Drawable iconDrawable = null;
Drawable iconDrawable;
Resources res = activity.getResources();
// 获取 Activity icon
try {
iconDrawable = res.getDrawable(ai.icon);
if (LOG) {
LogDebug.d(TAG, "ai.icon = " + iconDrawable);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 ai.icon 失败");
}
e.printStackTrace();
}
iconDrawable = getIconById(res, ai.icon);
// 获取插件 Application Icon
if (iconDrawable == null) {
try {
iconDrawable = res.getDrawable(ai.applicationInfo.icon);
if (LOG) {
LogDebug.d(TAG, "ai.application.icon = " + iconDrawable);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 ai.application.icon 失败");
}
e.printStackTrace();
}
iconDrawable = getIconById(res, ai.applicationInfo.icon);
}
// 获取 App(Host) Icon
if (iconDrawable == null) {
try {
Context appContext = RePluginInternal.getAppContext();
Resources appResource = appContext.getResources();
ApplicationInfo appInfo = appContext.getApplicationInfo();
iconDrawable = appResource.getDrawable(appInfo.icon);
if (LOG) {
LogDebug.d(TAG, "host.application.icon = " + iconDrawable);
}
} catch (Resources.NotFoundException e) {
if (LOG) {
LogDebug.d(TAG, "获取 host.application.icon 失败");
}
e.printStackTrace();
}
Context appContext = RePluginInternal.getAppContext();
Resources appResource = appContext.getResources();
ApplicationInfo appInfo = appContext.getApplicationInfo();
iconDrawable = getIconById(appResource, appInfo.icon);
}
Bitmap bitmap = null;
@ -256,4 +198,16 @@ public class ActivityInjector {
}
return bitmap;
}
private static Drawable getIconById(Resources res, int id) {
if (id == 0) {
return null;
}
try {
return res.getDrawable(id);
} catch (Resources.NotFoundException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -190,24 +190,38 @@ public class PluginInfo implements Parcelable, Cloneable {
* 注意框架内部接口外界请不要直接使用
*/
public static PluginInfo parseFromPackageInfo(PackageInfo pi, String path) {
// TODO 需要改插件的plugin.gradle
ApplicationInfo ai = pi.applicationInfo;
if (ai == null) {
// 几乎不可能但为保险起见返回Null
return null;
}
String pn = pi.packageName;
String alias = null;
int low = 0;
int high = 0;
int ver = 0;
Bundle metaData = ai.metaData;
// 获取插件包名和插件别名如有如无则将"包名"当做插件名
String pn = pi.packageName;
String alias = metaData.getString("com.qihoo360.plugin.name");
// 优先读取MetaData中的内容如有并覆盖上面的默认值
if (metaData != null) {
// 获取插件别名如有如无则将"包名"当做插件名
alias = metaData.getString("com.qihoo360.plugin.name");
// 获取最低/最高协议版本默认为应用的最小支持版本以保证一定能在宿主中运行
int low = metaData.getInt("com.qihoo360.plugin.version.low", Constant.ADAPTER_COMPATIBLE_VERSION);
int high = metaData.getInt("com.qihoo360.plugin.version.high", Constant.ADAPTER_COMPATIBLE_VERSION);
// 获取最低/最高协议版本默认为应用的最小支持版本以保证一定能在宿主中运行
low = metaData.getInt("com.qihoo360.plugin.version.low");
high = metaData.getInt("com.qihoo360.plugin.version.high");
// 获取插件的版本号优先从metaData中读取如无则使用插件的VersionCode
int ver = metaData.getInt("com.qihoo360.plugin.version.ver");
if (ver <= 0) {
ver = pi.versionCode;
// 获取插件的版本号优先从metaData中读取如无则使用插件的VersionCode
ver = metaData.getInt("com.qihoo360.plugin.version.ver");
}
// 针对有问题的字段做除错处理
if (low <= 0) { low = Constant.ADAPTER_COMPATIBLE_VERSION; }
if (high <= 0) { high = Constant.ADAPTER_COMPATIBLE_VERSION; }
if (ver <= 0) { ver = pi.versionCode; }
PluginInfo pli = new PluginInfo(pn, alias, low, high, ver, path, PluginInfo.TYPE_NOT_INSTALL);
// 获取插件的框架版本号

View File

@ -20,12 +20,11 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.qihoo360.replugin.DefaultRePluginCallbacks;
import com.qihoo360.replugin.DefaultRePluginEventCallbacks;
import com.qihoo360.replugin.RePlugin;
import com.qihoo360.replugin.RePluginApplication;
import com.qihoo360.replugin.RePluginCallbacks;
import com.qihoo360.replugin.RePluginConfig;
import com.qihoo360.replugin.RePluginEventCallbacks;
/**
* @author RePlugin Team
@ -74,7 +73,7 @@ public class SampleApplication extends RePluginApplication {
/**
* 宿主针对RePlugin的自定义行为
*/
private class HostCallbacks extends DefaultRePluginCallbacks {
private class HostCallbacks extends RePluginCallbacks {
private static final String TAG = "HostCallbacks";
@ -93,7 +92,7 @@ public class SampleApplication extends RePluginApplication {
}
}
private class HostEventCallbacks extends DefaultRePluginEventCallbacks {
private class HostEventCallbacks extends RePluginEventCallbacks {
private static final String TAG = "HostEventCallbacks";