private void set(String name) { LogUtil.d("attach " + name); Object obj = RefInvoker.getFieldObject(this, Activity.class.getName(), name); if (obj != null) { RefInvoker.setFieldObject(activity, Activity.class.getName(), name, obj); } }
/** * 这里需要attach的值 根据不同的android版本和厂商版本,可能会有所不同 需要实际测试后才能保证兼容 * * <p>这里后续还需要考虑对不同android版本的差异性支持,attach的代码是基于Android L的实现 * * <p>重要:由于作者设备有限,以下内容仅在 小米2s 4.1.1 系统上测试过。 */ private void attach() { RefInvoker.invokeMethod( activity, ContextWrapper.class.getName(), "attachBaseContext", new Class[] {Context.class}, new Object[] {getBaseContext()}); set("mWindow"); set("mUiThread"); set("mMainThread"); set("mInstrumentation"); set("mToken"); set("mIdent"); set("mApplication"); set("mIntent"); set("mComponent"); set("mActivityInfo"); set("mTitle"); set("mParent"); set("mEmbeddedID"); set("mLastNonConfigurationInstances"); // set("mVoiceInteractor"); set("mFragments"); set("mWindowManager"); set("mCurrentConfig"); }
protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); RefInvoker.invokeMethod( activity, Activity.class.getName(), "onPostCreate", new Class[] {Bundle.class}, new Object[] {savedInstanceState}); }
@Override protected void onSaveInstanceState(Bundle outState) { RefInvoker.invokeMethod( activity, Activity.class.getName(), "onSaveInstanceState", new Class[] {Bundle.class}, new Object[] {outState}); }
@Override protected void onNewIntent(Intent intent) { RefInvoker.invokeMethod( activity, Activity.class.getName(), "onNewIntent", new Class[] {Intent.class}, new Object[] {intent}); }
@Override public boolean onPrepareOptionsMenu(Menu menu) { return (Boolean) RefInvoker.invokeMethod( activity, Activity.class.getName(), "onPrepareOptionsMenu", new Class[] {Menu.class}, new Object[] {menu}); }
@Override public boolean onOptionsItemSelected(MenuItem item) { return (Boolean) RefInvoker.invokeMethod( activity, Activity.class.getName(), "onOptionsItemSelected", new Class[] {MenuItem.class}, new Object[] {item}); }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { RefInvoker.invokeMethod( activity, Activity.class.getName(), "onActivityResult", new Class[] { Integer.class, Integer.class, Intent.class, }, new Object[] {requestCode, resultCode, data}); }
@Override public void onCreate(Bundle savedInstanceState) { Context pctx = findPluginContext(); bindPluginContext(pctx); super.onCreate(savedInstanceState); FrameLayout root = new FrameLayout(this); setContentView(root, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); root.setId(android.R.id.primary); loadPluginActivity(); attach(); RefInvoker.invokeMethod( activity, Activity.class.getName(), "onCreate", new Class[] {Bundle.class}, new Object[] {savedInstanceState}); }
/** * for eclipse & ant with public.xml * * <p>unused * * @param pluginDescriptor * @param res * @return */ private static boolean checkPluginPublicXml(PluginDescriptor pluginDescriptor, Resources res) { // "plugin_layout_1"资源id时由public.xml配置的 // 如果没有检测到这个资源,说明编译时没有引入public.xml, // 这里直接抛个异常出去。 // 不同的系统版本获取id的方式不同, // 三星4.x等系统适用 int publicStub = res.getIdentifier("plugin_layout_1", "layout", pluginDescriptor.getPackageName()); if (publicStub == 0) { // 小米5.x等系统适用 publicStub = res.getIdentifier("plugin_layout_1", "layout", sApplication.getPackageName()); } if (publicStub == 0) { try { // 如果以上两种方式都检测失败,最后尝试通过反射检测 Class layoutClass = ((ClassLoader) pluginDescriptor.getPluginClassLoader()) .loadClass(pluginDescriptor.getPackageName() + ".R$layout"); Integer layouId = (Integer) RefInvoker.getFieldObject(null, layoutClass, "plugin_layout_1"); if (layouId != null) { publicStub = layouId; } } catch (ClassNotFoundException e) { e.printStackTrace(); } } if (publicStub == 0) { throw new IllegalStateException( "\n插件工程没有使用public.xml给资源id分组!!!\n" + "插件工程没有使用public.xml给资源id分组!!!\n" + "插件工程没有使用public.xml给资源id分组!!!\n" + "重要的事情讲三遍!!!"); } return true; }
@Override protected void onDestroy() { super.onDestroy(); RefInvoker.invokeMethod( activity, Activity.class.getName(), "onDestroy", new Class[] {}, new Object[] {}); }