Android Open Source - AndroidPlugin Activity Overider






From Project

Back to project page AndroidPlugin.

License

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.

Java Source Code

/*
 * 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);
        }
    }
}




Java Source Code List

android.widget.ViewStub.java
androidx.plmgrdemo.MainActivity.java
androidx.plmgrdemo.PlugListViewAdapter.java
androidx.pluginmgr.ActivityClassGenerator.java
androidx.pluginmgr.ActivityOverider.java
androidx.pluginmgr.FileUtil.java
androidx.pluginmgr.FrameworkClassLoader.java
androidx.pluginmgr.LayoutInflaterWrapper.java
androidx.pluginmgr.PlugInfo.java
androidx.pluginmgr.PluginActivityLifeCycleCallback.java
androidx.pluginmgr.PluginClassLoader.java
androidx.pluginmgr.PluginContextWrapper.java
androidx.pluginmgr.PluginManager.java
androidx.pluginmgr.PluginManifestUtil.java
androidx.pluginmgr.ReflectionUtils.java
androidx.pluginmgr.XmlManifestReader.java
com.limemobile.app.demo.pluginclienta.ClientABindService.java
com.limemobile.app.demo.pluginclienta.ClientAStartedService.java
com.limemobile.app.demo.pluginclienta.MainActivity.java
com.limemobile.app.demo.pluginclienta.TestButton.java
com.limemobile.app.demo.pluginclienta.TestFragmentActivity.java
com.limemobile.app.demo.pluginclienta.TestFragment.java
com.limemobile.app.demo.pluginclientb.ClientBStartedService.java
com.limemobile.app.demo.pluginclientb.MainActivity.java
com.limemobile.app.demo.pluginhost.HostBindService.java
com.limemobile.app.demo.pluginhost.HostStartedService.java
com.limemobile.app.demo.pluginhost.MainActivity.java
com.limemobile.app.demo.pluginhost.MyApplication.java
com.limemobile.app.demo.pluginhost.TestHostClass.java
com.limemobile.app.plugin.IPluginActivity.java
com.limemobile.app.plugin.IPluginContentProvider.java
com.limemobile.app.plugin.IPluginService.java
com.limemobile.app.plugin.PluginClientActivity.java
com.limemobile.app.plugin.PluginClientFragmentActivity.java
com.limemobile.app.plugin.PluginClientService.java
com.limemobile.app.plugin.PluginHostApplication.java
com.limemobile.app.plugin.PluginHostContentProvider.java
com.limemobile.app.plugin.PluginHostDelegateActivity.java
com.limemobile.app.plugin.PluginHostDelegateContentProvider.java
com.limemobile.app.plugin.PluginHostDelegateFragmentActivity.java
com.limemobile.app.plugin.PluginHostDelegateService.java
com.limemobile.app.plugin.internal.IPluginActivityDelegate.java
com.limemobile.app.plugin.internal.IPluginContentProviderDelegate.java
com.limemobile.app.plugin.internal.IPluginServiceDelegate.java
com.limemobile.app.plugin.internal.PluginClientDexClassLoader.java
com.limemobile.app.plugin.internal.PluginClientInfo.java
com.limemobile.app.plugin.internal.PluginClientManager.java
com.limemobile.app.plugin.internal.PluginDelegateActivityImpl.java
com.limemobile.app.plugin.internal.PluginDelegateContentProviderImpl.java
com.limemobile.app.plugin.internal.PluginDelegateServiceImpl.java
com.limemobile.app.plugin.internal.ReflectFieldAccessor.java