Skip to content

Commit

Permalink
Merge pull request #290 from jiongxuan/feature_get_resource
Browse files Browse the repository at this point in the history
Added "Fetch ResourceId/View in other plugins"
  • Loading branch information
cundong authored Aug 10, 2017
2 parents 926022f + 4a2dfdb commit 766bdf7
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
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;
Expand Down Expand Up @@ -473,6 +476,76 @@ public static String fetchPluginNameByClassLoader(ClassLoader cl) {
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);
}

/**
* 获取所有插件的列表(指已安装的)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
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;
Expand All @@ -44,6 +46,8 @@

public class RePlugin {

static final String TAG = "RePlugin";

/**
* 表示目标进程根据实际情况自动调配
*/
Expand Down Expand Up @@ -512,6 +516,42 @@ public static String fetchPluginNameByClassLoader(ClassLoader cl) {
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);
}

/**
* 获取所有插件的列表(指已安装的)
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
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;
Expand Down Expand Up @@ -277,15 +275,11 @@ public void onClick(View v) {
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();
Expand Down

0 comments on commit 766bdf7

Please sign in to comment.