Back to project page AndroidPlugin.
The source code is released under:
MIT License
If you think the Android project AndroidPlugin listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) 2015 HouKx <hkx.aidream@gmail.com> *//from ww w . j av a2 s . c om * 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 androidx.pluginmgr; import java.io.File; import java.lang.reflect.Field; import android.app.Activity; import android.content.ComponentName; import android.content.ContextWrapper; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.os.Bundle; import android.util.Log; import android.view.Window; /** * ???????????????Activity?? * * @author HouKangxi */ public class ActivityOverider { private static final String tag = "ActivityOverider"; /** * ?????? Activity ?????? */ static final String targetClassName = "androidx.pluginmgr.PluginActivity"; // ------------------- process service --------- /** * ?? StarService ?? * * @param intent * @param fromAct */ public static ComponentName overrideStartService(Activity fromAct, String pluginId, Intent intent) { // TODO ?? StarService ?? Log.d(tag, "overrideStartService"); return fromAct.startService(intent); } public static boolean overrideBindService(Activity fromAct, String pluginId, Intent intent, ServiceConnection conn, int flags) { // TODO overrideBindService Log.d(tag, "overrideBindService"); return fromAct.bindService(intent, conn, flags); } public static void overrideUnbindService(Activity fromAct, String pluginId, ServiceConnection conn) { // TODO overrideUnbindService Log.d(tag, "overrideUnbindService"); fromAct.unbindService(conn); } public static boolean overrideStopService(Activity fromAct, String pluginId, Intent intent) { // TODO overrideStopService Log.d(tag, "overrideStopService"); return fromAct.stopService(intent); } // ------------------ process Activity --------------------------- /** * ???? ????Activity ?? intent ?????Activity * <p> * ??????? startActivity ?? * * @param fromAct * - ???????Activity * @param pluginId * - ????id * @param intent * - ??????Activity?Intent?? * @param requestCode * @param options * @return ?????? Intent */ public static Intent overrideStartActivityForResult(Activity fromAct, String pluginId, Intent intent, int requestCode, Bundle options) { // ??????????? // 1 ????Intent????? // 2 ??????????????????activity???? PluginManager mgr = PluginManager.getInstance(); // ???????????????????? Action if (intent.getComponent() != null && intent.getComponent().getClassName() != null) { // action ????????????? activity???? ComponentName compname = intent.getComponent(); String pkg = compname.getPackageName(); String toActName = compname.getClassName(); PlugInfo thisPlugin = mgr.getPluginById(pluginId); ActivityInfo actInThisApk = null; if (pkg != null) { if (pkg.equals(thisPlugin.getPackageName())) { actInThisApk = thisPlugin .findActivityByClassName(toActName); } } else { actInThisApk = thisPlugin.findActivityByClassName(toActName); } if (actInThisApk != null) { setPluginIntent(intent, thisPlugin, actInThisApk.name); } else { for (PlugInfo plugInfo : mgr.getPlugins()) { if (plugInfo == thisPlugin) { continue; } ActivityInfo otherAct = plugInfo .findActivityByClassName(toActName); if (otherAct != null) { setPluginIntent(intent, plugInfo, otherAct.name); break; } } } } else if (intent.getAction() != null) { String action = intent.getAction(); // // ?????? action // ???activity????????????action,?????????????????????????? PlugInfo thisPlugin = mgr.getPluginById(pluginId); ActivityInfo actInThisApk = thisPlugin.findActivityByAction(action); if (actInThisApk != null) { setPluginIntent(intent, thisPlugin, actInThisApk.name); } else { for (PlugInfo plugInfo : mgr.getPlugins()) { if (plugInfo == thisPlugin) { continue; } ActivityInfo otherAct = plugInfo .findActivityByAction(action); if (otherAct != null) { setPluginIntent(intent, plugInfo, otherAct.name); break; } } } } return intent; } private static void setPluginIntent(Intent intent, PlugInfo plugin, String actName) { PluginManager mgr = PluginManager.getInstance(); String pluginId = plugin.getId(); createProxyDex(plugin, actName); String act = mgr.getFrameworkClassLoader().newActivityClassName( pluginId, actName); ComponentName compname = new ComponentName(mgr.getContext(), act); intent.setComponent(compname); } static File getPluginBaseDir(String pluginId) { String pluginPath = PluginManager.getInstance() .getDexInternalStoragePath().getAbsolutePath(); String pluginDir = pluginPath + '/' + pluginId + "-dir/"; File folder = new File(pluginDir); folder.mkdirs(); return folder; } static File getPluginLibDir(String pluginId) { File folder = new File(getPluginBaseDir(pluginId) + "/lib/"); return folder; } static File getPorxyActivityDexPath(String pluginId, String activity) { File folder = new File(getPluginBaseDir(pluginId) + "/activities/"); folder.mkdirs(); String suffix = ".dex"; if (android.os.Build.VERSION.SDK_INT < 11) { suffix = ".jar"; } File savePath = new File(folder, activity + suffix); return savePath; } static File createProxyDex(PlugInfo plugin, String activity) { return createProxyDex(plugin, activity, true); } static File createProxyDex(PlugInfo plugin, String activity, boolean lazy) { File savePath = getPorxyActivityDexPath(plugin.getId(), activity); createProxyDex(plugin, activity, savePath, lazy); return savePath; } private static void createProxyDex(PlugInfo plugin, String activity, File saveDir, boolean lazy) { // Log.d(tag + ":createProxyDex", "plugin=" + plugin + "\n, activity=" // + activity); if (lazy && saveDir.exists()) { // Log.d(tag, "dex alreay exists: " + saveDir); // ???????????????? return; } // Log.d(tag, "actName=" + actName + ", saveDir=" + saveDir); try { String pkgName = plugin.getPackageName(); ActivityClassGenerator.createActivityDex(activity, targetClassName, saveDir, plugin.getId(), pkgName); } catch (Throwable e) { Log.e(tag, Log.getStackTraceString(e)); } } /** * ??pluginId??AssetManager * <p> * ??????? onCreate()??? (super.onCreate()???)?? <br/> * ????????????????????activity * * @param pluginId * -????Id * @param fromAct * - ???????Activity * @return */ public static AssetManager getAssetManager(String pluginId, Activity fromAct) { PlugInfo rsinfo = PluginManager.getInstance().getPluginById(pluginId); // fromAct.getApplicationContext(); try { Field f = ContextWrapper.class.getDeclaredField("mBase"); f.setAccessible(true); f.set(fromAct, rsinfo.getApplication()); } catch (Exception e) { Log.e(tag, Log.getStackTraceString(e)); } // ?????Galaxy S4 ?????????LayoutInflater?????LayoutInflater // ???????????????????????? if (android.os.Build.MODEL.equals("GT-I9500")) { Window window = fromAct.getWindow();// ?? PhoneWindow ?? try { ReflectionUtils.setFieldValue(window, "mLayoutInflater", new LayoutInflaterWrapper(window.getLayoutInflater())); } catch (Exception e) { Log.e(tag, Log.getStackTraceString(e)); } } return rsinfo.getAssetManager(); } /** * ??back?????? * * @param pluginId * @param fromAct * @return ?????????onBackPressed()?? */ public static boolean overrideOnbackPressed(Activity fromAct, String pluginId) { PlugInfo plinfo = PluginManager.getInstance().getPluginById(pluginId); String actName = fromAct.getClass().getSuperclass().getName(); ActivityInfo actInfo = plinfo.findActivityByClassName(actName); boolean finish = plinfo.isFinishActivityOnbackPressed(actInfo); if (finish) { fromAct.finish(); } boolean ivsuper = plinfo.isInvokeSuperOnbackPressed(actInfo); Log.d(tag, "finish? " + finish + ", ivsuper? " + ivsuper); return ivsuper; } // // =================== Activity ???????? ================== // public static void callback_onCreate(String pluginId, Activity fromAct) { PluginManager con = PluginManager.getInstance(); // setTheme PlugInfo plugin = con.getPluginById(pluginId); String actName = fromAct.getClass().getSuperclass().getName(); Log.d(tag, "pluginId = " + plugin + ", actName = " + actName + ", simpleName=" + fromAct.getClass().getSuperclass().getSimpleName()); ActivityInfo actInfo = plugin.findActivityByClassName(actName); int themeResId = actInfo.theme; Log.d(tag, "actTheme=" + themeResId); if (themeResId == 0) { themeResId = plugin.getPackageInfo().applicationInfo.theme; Log.d(tag, "applicationTheme=" + themeResId); } if (themeResId != 0) { fromAct.setTheme(themeResId); } // invoke callback PluginActivityLifeCycleCallback callback = con .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onCreate(pluginId, fromAct); } } public static void callback_onResume(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onResume(pluginId, fromAct); } } public static void callback_onStart(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onStart(pluginId, fromAct); } } public static void callback_onRestart(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onRestart(pluginId, fromAct); } } public static void callback_onPause(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onPause(pluginId, fromAct); } } public static void callback_onStop(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onStop(pluginId, fromAct); } } public static void callback_onDestroy(String pluginId, Activity fromAct) { PluginActivityLifeCycleCallback callback = PluginManager.getInstance() .getPluginActivityLifeCycleCallback(); if (callback != null) { callback.onDestroy(pluginId, fromAct); } } }