mirror of
https://gitee.com/replugin/RePlugin.git
synced 2024-12-02 03:38:06 +08:00
Merge pull request #290 from jiongxuan/feature_get_resource
Added "Fetch ResourceId/View in other plugins"
This commit is contained in:
commit
766bdf741e
@ -32,6 +32,9 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.qihoo360.i.Factory;
|
||||
import com.qihoo360.i.Factory2;
|
||||
@ -473,6 +476,76 @@ public class RePlugin {
|
||||
return Factory.fetchPluginName(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过资源名(包括前缀和具体名字),来获取指定插件里的资源的ID
|
||||
* <p>
|
||||
* 性能消耗:等同于 fetchResources
|
||||
*
|
||||
* @param pluginName 插件名
|
||||
* @param resTypeAndName 要获取的“资源类型+资源名”,格式为:“[type]/[name]”。例如: <p>
|
||||
* → layout/common_title → 从“布局”里获取common_title的ID <p>
|
||||
* → drawable/common_bg → 从“可绘制图片”里获取common_bg的ID <p>
|
||||
* 详细见Android官方的说明
|
||||
* @return 资源的ID。若为0,则表示资源没有找到,无法使用
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public static int fetchResourceIdByName(String pluginName, String resTypeAndName) {
|
||||
PackageInfo pi = fetchPackageInfo(pluginName);
|
||||
if (pi == null) {
|
||||
// 插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchResourceIdByName: Plugin not found. pn=" + pluginName + "; resName=" + resTypeAndName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Resources res = fetchResources(pluginName);
|
||||
if (res == null) {
|
||||
// 不太可能出现此问题,同样为插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchResourceIdByName: Plugin not found (fetchResources). pn=" + pluginName + "; resName=" + resTypeAndName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Identifier的第一个参数想要的是:
|
||||
// [包名]:[类型名]/[资源名]。其中[类型名]/[资源名]就是 resTypeAndName 参数
|
||||
// 例如:com.qihoo360.replugin.sample.demo2:layout/from_demo1
|
||||
String idKey = pi.packageName + ":" + resTypeAndName;
|
||||
return res.getIdentifier(idKey, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Layout名,来获取插件内的View
|
||||
*
|
||||
* @param pluginName 插件名
|
||||
* @param layoutName Layout名字
|
||||
* @param root Optional view to be the parent of the generated hierarchy.
|
||||
* @return 插件的View。若为Null则表示获取失败
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public static View fetchViewByLayoutName(String pluginName, String layoutName, ViewGroup root) {
|
||||
Context context = fetchContext(pluginName);
|
||||
if (context == null) {
|
||||
// 插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchViewByLayoutName: Plugin not found. pn=" + pluginName + "; layoutName=" + layoutName);
|
||||
}
|
||||
}
|
||||
|
||||
String resTypeAndName = "layout/" + layoutName;
|
||||
int id = fetchResourceIdByName(pluginName, resTypeAndName);
|
||||
if (id <= 0) {
|
||||
// 无法拿到资源,可能是资源没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchViewByLayoutName: fetch failed! pn=" + pluginName + "; layoutName=" + layoutName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO 可能要考虑WebView在API 19以上的特殊性
|
||||
return LayoutInflater.from(context).inflate(id, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件的列表(指已安装的)
|
||||
*
|
||||
|
@ -25,12 +25,14 @@ import android.content.res.Resources;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.qihoo360.replugin.i.IPluginManager;
|
||||
import com.qihoo360.replugin.utils.ParcelUtils;
|
||||
import com.qihoo360.replugin.helper.LogDebug;
|
||||
import com.qihoo360.replugin.i.IPluginManager;
|
||||
import com.qihoo360.replugin.model.PluginInfo;
|
||||
import com.qihoo360.replugin.packages.PluginRunningList;
|
||||
import com.qihoo360.replugin.utils.ParcelUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -44,6 +46,8 @@ import java.util.List;
|
||||
|
||||
public class RePlugin {
|
||||
|
||||
static final String TAG = "RePlugin";
|
||||
|
||||
/**
|
||||
* 表示目标进程根据实际情况自动调配
|
||||
*/
|
||||
@ -512,6 +516,42 @@ public class RePlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过资源名(包括前缀和具体名字),来获取指定插件里的资源的ID
|
||||
* <p>
|
||||
* 性能消耗:等同于 fetchResources
|
||||
*
|
||||
* @param pluginName 插件名
|
||||
* @param resTypeAndName 要获取的“资源类型+资源名”,格式为:“[type]/[name]”。例如: <p>
|
||||
* → layout/common_title → 从“布局”里获取common_title的ID <p>
|
||||
* → drawable/common_bg → 从“可绘制图片”里获取common_bg的ID <p>
|
||||
* 详细见Android官方的说明
|
||||
* @return 资源的ID。若为0,则表示资源没有找到,无法使用
|
||||
* @since 2.2.0 (老的host-lib版本也能使用)
|
||||
*/
|
||||
public static int fetchResourceIdByName(String pluginName, String resTypeAndName) {
|
||||
if (!RePluginFramework.mHostInitialized) {
|
||||
return 0;
|
||||
}
|
||||
return RePluginCompat.fetchResourceIdByName(pluginName, resTypeAndName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Layout名,来获取插件内的View
|
||||
*
|
||||
* @param pluginName 插件名
|
||||
* @param layoutName Layout名字
|
||||
* @param root Optional view to be the parent of the generated hierarchy.
|
||||
* @return 插件的View。若为Null则表示获取失败
|
||||
* @since 2.2.0 (老的host-lib版本也能使用)
|
||||
*/
|
||||
public static View fetchViewByLayoutName(String pluginName, String layoutName, ViewGroup root) {
|
||||
if (!RePluginFramework.mHostInitialized) {
|
||||
return null;
|
||||
}
|
||||
return RePluginCompat.fetchViewByLayoutName(pluginName, layoutName, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件的列表(指已安装的)
|
||||
*
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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 android.content.pm.PackageInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.qihoo360.replugin.helper.LogDebug;
|
||||
|
||||
import static com.qihoo360.replugin.RePlugin.TAG;
|
||||
import static com.qihoo360.replugin.RePlugin.fetchContext;
|
||||
import static com.qihoo360.replugin.RePlugin.fetchPackageInfo;
|
||||
import static com.qihoo360.replugin.RePlugin.fetchResources;
|
||||
|
||||
/**
|
||||
* 为了兼容旧版本RePlugin而做的类 <p>
|
||||
* 必须和host-lib中的方法“近乎完全一样”才可以,避免出现行为不一致的问题 <p>
|
||||
* <p>
|
||||
* 注意:依赖host-lib内部调用的(例如调用了Loader的逻辑等)、或者行为高度和宿主一致的,则还是应该走正常的反射流程
|
||||
*
|
||||
* @author RePlugin Team
|
||||
* @since 2.2.0
|
||||
*/
|
||||
|
||||
class RePluginCompat {
|
||||
|
||||
/**
|
||||
* @see RePlugin#fetchResourceIdByName(String, String)
|
||||
*/
|
||||
static int fetchResourceIdByName(String pluginName, String resTypeAndName) {
|
||||
PackageInfo pi = fetchPackageInfo(pluginName);
|
||||
if (pi == null) {
|
||||
// 插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchResourceIdByName: Plugin not found. pn=" + pluginName + "; resName=" + resTypeAndName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Resources res = fetchResources(pluginName);
|
||||
if (res == null) {
|
||||
// 不太可能出现此问题,同样为插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchResourceIdByName: Plugin not found (fetchResources). pn=" + pluginName + "; resName=" + resTypeAndName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Identifier的第一个参数想要的是:
|
||||
// [包名]:[类型名]/[资源名]。其中[类型名]/[资源名]就是 resTypeAndName 参数
|
||||
// 例如:com.qihoo360.replugin.sample.demo2:layout/from_demo1
|
||||
String idKey = pi.packageName + ":" + resTypeAndName;
|
||||
return res.getIdentifier(idKey, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RePlugin#fetchViewByLayoutName(String, String, ViewGroup)
|
||||
*/
|
||||
static View fetchViewByLayoutName(String pluginName, String layoutName, ViewGroup root) {
|
||||
Context context = fetchContext(pluginName);
|
||||
if (context == null) {
|
||||
// 插件没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchViewByLayoutName: Plugin not found. pn=" + pluginName + "; layoutName=" + layoutName);
|
||||
}
|
||||
}
|
||||
|
||||
String resTypeAndName = "layout/" + layoutName;
|
||||
int id = fetchResourceIdByName(pluginName, resTypeAndName);
|
||||
if (id <= 0) {
|
||||
// 无法拿到资源,可能是资源没有找到
|
||||
if (LogDebug.LOG) {
|
||||
LogDebug.e(TAG, "fetchViewByLayoutName: fetch failed! pn=" + pluginName + "; layoutName=" + layoutName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO 可能要考虑WebView在API 19以上的特殊性
|
||||
return LayoutInflater.from(context).inflate(id, root);
|
||||
}
|
||||
}
|
@ -22,14 +22,12 @@ import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
@ -277,15 +275,11 @@ public class MainActivity extends Activity {
|
||||
mItems.add(new TestItem("Resources: Use demo2's layout", new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Resources res = RePlugin.fetchResources("demo2");
|
||||
int id = res.getIdentifier("com.qihoo360.replugin.sample.demo2:layout/from_demo1", null, null);
|
||||
if (id == 0) {
|
||||
View contentView = RePlugin.fetchViewByLayoutName("demo2", "from_demo1", null);
|
||||
if (contentView == null) {
|
||||
Toast.makeText(v.getContext(), "from_demo1 Not Found", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// 这块儿得拿demo2的Context,才能Inflate到资源
|
||||
View contentView = LayoutInflater.from(RePlugin.fetchContext("demo2")).inflate(id, null);
|
||||
Dialog d = new Dialog(v.getContext());
|
||||
d.setContentView(contentView);
|
||||
d.show();
|
||||
|
Loading…
Reference in New Issue
Block a user