diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLApplicationContext.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLApplicationContext.java new file mode 100644 index 0000000..fe64570 --- /dev/null +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLApplicationContext.java @@ -0,0 +1,84 @@ +package com.ryg.dynamicload; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.res.AssetManager; +import android.content.res.Resources; + +import com.ryg.dynamicload.internal.DLIntent; +import com.ryg.dynamicload.internal.DLPluginManager; +import com.ryg.dynamicload.internal.DLPluginPackage; + +/** + * 插件app的application上下文 + * 主要用在单例中对applicaiton上下文的使用 + */ +public class DLApplicationContext extends ContextWrapper { + + DLPluginPackage mPluginPackage; + + public DLApplicationContext(Context base, DLPluginPackage pluginPkg) { + super(base); + mPluginPackage = pluginPkg; + } + + + @Override + public Resources getResources() { + if(mPluginPackage != null){ + return mPluginPackage.resources; + }else{ + return super.getResources(); + } + } + + @Override + public Context getApplicationContext() { + if(mPluginPackage != null){ + return this; + }else{ + return super.getApplicationContext(); + } + } + + @Override + public String getPackageName() { + if(mPluginPackage != null){ + return mPluginPackage.packageName; + }else{ + return super.getPackageName(); + } + } + + @Override + public AssetManager getAssets() { + if(mPluginPackage != null){ + return mPluginPackage.assetManager; + }else{ + return super.getAssets(); + } + } + + @Override + public void startActivity(Intent intent) { + if(mPluginPackage != null){ + startPluginActivity((DLIntent) intent); + }else{ + super.startActivity(intent); + } + } + + public void startPluginActivity(DLIntent dlIntent) { + startPluginActivityForResult(dlIntent, -1); + } + + public void startPluginActivityForResult(DLIntent dlIntent, int requestCode) { + if (dlIntent.getPluginPackage() == null) { + dlIntent.setPluginPackage(mPluginPackage.packageName); + } + DLPluginManager plMgr = DLPluginManager.getInstance(this); + plMgr.startPluginActivityForResult(this, dlIntent, requestCode); + } + +} diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginActivity.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginActivity.java index b247f33..1cf7779 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginActivity.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginActivity.java @@ -19,9 +19,10 @@ package com.ryg.dynamicload; import android.app.Activity; -import android.content.ComponentName; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.res.Resources; @@ -363,30 +364,23 @@ public boolean onOptionsItemSelected(MenuItem item) { return false; } - /** - * @param dlIntent - * @return may be {@link #START_RESULT_SUCCESS}, - * {@link #START_RESULT_NO_PKG}, {@link #START_RESULT_NO_CLASS}, - * {@link #START_RESULT_TYPE_ERROR} - */ - public int startPluginActivity(DLIntent dlIntent) { - return startPluginActivityForResult(dlIntent, -1); - } - - /** - * @param dlIntent - * @return may be {@link #START_RESULT_SUCCESS}, - * {@link #START_RESULT_NO_PKG}, {@link #START_RESULT_NO_CLASS}, - * {@link #START_RESULT_TYPE_ERROR} - */ - public int startPluginActivityForResult(DLIntent dlIntent, int requestCode) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) { - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - } - return mPluginManager.startPluginActivityForResult(that, dlIntent, requestCode); - } + @Override + public void startActivity(Intent intent) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.startActivity(intent); + } else { + mProxyActivity.startActivity(intent); + } + } + + @Override + public void startActivityForResult(Intent intent, int requestCode) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.startActivityForResult(intent, requestCode); + } else { + mProxyActivity.startActivityForResult(intent, requestCode); + } + } public int startPluginService(DLIntent dlIntent) { if (mFrom == DLConstants.FROM_EXTERNAL) { @@ -397,14 +391,24 @@ public int startPluginService(DLIntent dlIntent) { return mPluginManager.startPluginService(that, dlIntent); } - public int bindPluginService(DLIntent dlIntent, ServiceConnection conn, int flags) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) { - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - } - return mPluginManager.bindPluginService(that, dlIntent, conn, flags); - } +// public int stopPluginService(DLIntent dlIntent) { +// if (mFrom == DLConstants.FROM_EXTERNAL) { +// if (dlIntent.getPluginPackage() == null) { +// dlIntent.setPluginPackage(mPluginPackage.packageName); +// } +// } +// return mPluginManager.stopPluginService(that, dlIntent); +// } + + public int bindPluginService(DLIntent dlIntent, ServiceConnection conn, + int flags) { + if (mFrom == DLConstants.FROM_EXTERNAL) { + if (dlIntent.getPluginPackage() == null) { + dlIntent.setPluginPackage(mPluginPackage.packageName); + } + } + return mPluginManager.bindPluginService(that, dlIntent, conn, flags); + } public int unBindPluginService(DLIntent dlIntent, ServiceConnection conn) { if (mFrom == DLConstants.FROM_EXTERNAL) { @@ -414,33 +418,63 @@ public int unBindPluginService(DLIntent dlIntent, ServiceConnection conn) { return mPluginManager.unBindPluginService(that, dlIntent, conn); } - // /** - // * 直接调用that.startService - // * that 可能有两种情况 - // * 1.指向this - // * 2.指向DLProxyActivity - // */ - // public ComponentName startService(Intent service) { - // return that.startService(service); - // } - // - // @Override - // public boolean stopService(Intent name) { - // // TODO Auto-generated method stub - // return super.stopService(name); - // } - // - // @Override - // public boolean bindService(Intent service, ServiceConnection conn, int - // flags) { - // // TODO Auto-generated method stub - // return super.bindService(service, conn, flags); - // } - // - // @Override - // public void unbindService(ServiceConnection conn) { - // // TODO Auto-generated method stub - // super.unbindService(conn); - // } + @Override + public int checkPermission(String permission, int pid, int uid) { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.checkPermission(permission, pid, uid); + } else { + return mProxyActivity.checkPermission(permission, pid, uid); + } + } + + @Override + public boolean isFinishing() { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.isFinishing(); + } else { + return mProxyActivity.isFinishing(); + } + } + + @Override + public void sendBroadcast(Intent intent) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.sendBroadcast(intent); + } else { + mProxyActivity.sendBroadcast(intent); + } + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, + IntentFilter filter) { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.registerReceiver(receiver, filter); + } else { + return mProxyActivity.registerReceiver(receiver, filter); + } + } + + @Override + public void unregisterReceiver(BroadcastReceiver receiver) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.unregisterReceiver(receiver); + } else { + mProxyActivity.unregisterReceiver(receiver); + } + } + + @Override + public void onClick(View view) { + + } + + public View getCurrentFocus(){ + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getCurrentFocus(); + }else{ + return mProxyActivity.getCurrentFocus(); + } + } } diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginFragmentActivity.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginFragmentActivity.java index 9d35717..54d6f56 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginFragmentActivity.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/DLBasePluginFragmentActivity.java @@ -19,10 +19,15 @@ package com.ryg.dynamicload; import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; +import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.AssetManager; import android.content.res.Resources; import android.os.Bundle; import android.support.v4.app.FragmentActivity; @@ -41,7 +46,6 @@ import android.view.WindowManager; import com.ryg.dynamicload.internal.DLActivityPlugin; -import com.ryg.dynamicload.internal.DLIntent; import com.ryg.dynamicload.internal.DLPluginManager; import com.ryg.dynamicload.internal.DLPluginPackage; import com.ryg.utils.DLConstants; @@ -358,75 +362,151 @@ public boolean onOptionsItemSelected(MenuItem item) { return false; } - /** - * @param dlIntent - * @return may be {@link #START_RESULT_SUCCESS}, - * {@link #START_RESULT_NO_PKG}, {@link #START_RESULT_NO_CLASS}, - * {@link #START_RESULT_TYPE_ERROR} - */ - public int startPluginActivity(DLIntent dlIntent) { - return startPluginActivityForResult(dlIntent, -1); - } + // ------------------------------------------------------------------------ + // methods override from FragmentActivity + // ------------------------------------------------------------------------ + + @Override + public FragmentManager getSupportFragmentManager() { + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getSupportFragmentManager(); + }else{ + return mProxyActivity.getSupportFragmentManager(); + } + } + + @Override + public LoaderManager getSupportLoaderManager() { + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getSupportLoaderManager(); + }else{ + return mProxyActivity.getSupportLoaderManager(); + } + } + + @Override + public int checkPermission(String permission, int pid, int uid) { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.checkPermission(permission, pid, uid); + } else { + return mProxyActivity.checkPermission(permission, pid, uid); + } + } + + public boolean isFinishing() { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.isFinishing(); + } else { + return mProxyActivity.isFinishing(); + } + } + + @Override + public void sendBroadcast(Intent intent) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.sendBroadcast(intent); + } else { + mProxyActivity.sendBroadcast(intent); + } + } /** - * @param dlIntent - * @return may be {@link #START_RESULT_SUCCESS}, - * {@link #START_RESULT_NO_PKG}, {@link #START_RESULT_NO_CLASS}, - * {@link #START_RESULT_TYPE_ERROR} + * 插件apk直接调用上下文的startActivity即可调起activity + * @param intent */ - public int startPluginActivityForResult(DLIntent dlIntent, int requestCode) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) { - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - } - return mPluginManager.startPluginActivityForResult(that, dlIntent, requestCode); - } - - public int startPluginService(DLIntent dlIntent) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) { - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - } - return mPluginManager.startPluginService(that, dlIntent); - } - - public int bindPluginService(DLIntent dlIntent, ServiceConnection conn, int flags) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) { - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - } - return mPluginManager.bindPluginService(that, dlIntent, conn, flags); - } - - public int unBindPluginService(DLIntent dlIntent, ServiceConnection conn) { - if (mFrom == DLConstants.FROM_EXTERNAL) { - if (dlIntent.getPluginPackage() == null) - dlIntent.setPluginPackage(mPluginPackage.packageName); - } - return mPluginManager.unBindPluginService(that, dlIntent, conn); - } - - // ------------------------------------------------------------------------ - // methods override from FragmentActivity - // ------------------------------------------------------------------------ - - @Override - public FragmentManager getSupportFragmentManager() { - if (mFrom == DLConstants.FROM_INTERNAL) { - return super.getSupportFragmentManager(); - } - return mProxyActivity.getSupportFragmentManager(); - } - - @Override - public LoaderManager getSupportLoaderManager() { - if (mFrom == DLConstants.FROM_INTERNAL) { - return super.getSupportLoaderManager(); - } - return mProxyActivity.getSupportLoaderManager(); - } + @Override + public void startActivity(Intent intent) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.startActivity(intent); + } else { + mProxyActivity.startActivity(intent); + } + } + + @Override + public void startActivityForResult(Intent intent, int requestCode) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.startActivityForResult(intent, requestCode); + } else { + mProxyActivity.startActivityForResult(intent, requestCode); + } + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, + IntentFilter filter) { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.registerReceiver(receiver, filter); + } else { + return mProxyActivity.registerReceiver(receiver, filter); + } + } + + @Override + public void unregisterReceiver(BroadcastReceiver receiver) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.unregisterReceiver(receiver); + } else { + mProxyActivity.unregisterReceiver(receiver); + } + } + + public ApplicationInfo getApplicationInfo() { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.getApplicationInfo(); + } else { + return mProxyActivity.getApplicationInfo(); + } + } + + @Override + public PackageManager getPackageManager() { + if (mFrom == DLConstants.FROM_INTERNAL) { + return super.getPackageManager(); + } else { + return mProxyActivity.getPackageManager(); + } + } + + @Override + public void setTheme(int theme) { + if (mFrom == DLConstants.FROM_INTERNAL) { + super.setTheme(theme); + } else { + mProxyActivity.setTheme(theme); + } + } + + @Override + public ContentResolver getContentResolver() { + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getContentResolver(); + }else{ + return mProxyActivity.getContentResolver(); + } + } + + @Override + public void onClick(View view) { + + } + + @Override + public AssetManager getAssets() { + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getAssets(); + }else{ + return mProxyActivity.getAssets(); + } + } + + @Override + public View getCurrentFocus(){ + if(mFrom == DLConstants.FROM_INTERNAL){ + return super.getCurrentFocus(); + }else{ + return mProxyActivity.getCurrentFocus(); + } + } } diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLActivityPlugin.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLActivityPlugin.java index eac72d2..47cfc5b 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLActivityPlugin.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLActivityPlugin.java @@ -18,12 +18,15 @@ package com.ryg.dynamicload.internal; import android.app.Activity; +import android.content.BroadcastReceiver; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager.LayoutParams; public interface DLActivityPlugin extends DLAttachable{ @@ -46,4 +49,13 @@ public interface DLActivityPlugin extends DLAttachable{ public void onBackPressed(); public boolean onCreateOptionsMenu(Menu menu); public boolean onOptionsItemSelected(MenuItem item); + + public int checkPermission(String permission, int pid, int uid); + public void sendBroadcast(Intent intent); + public Intent registerReceiver(BroadcastReceiver receiver, + IntentFilter filter); + public void unregisterReceiver(BroadcastReceiver receiver); + public void setTheme(int theme); + public void onClick(View view); + public String getPackageName(); } diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLIntent.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLIntent.java index af42915..47118b9 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLIntent.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLIntent.java @@ -35,6 +35,17 @@ public class DLIntent extends Intent { public DLIntent() { super(); } + + public DLIntent(Intent intent){ + super(intent); + mPluginClass = intent.getComponent().getClassName(); + } + + public DLIntent(String pluginPackage, Intent intent){ + super(intent); + mPluginClass = intent.getComponent().getClassName(); + mPluginPackage = pluginPackage; + } public DLIntent(String pluginPackage) { super(); diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPackageManager.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPackageManager.java new file mode 100644 index 0000000..aeb0e7b --- /dev/null +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPackageManager.java @@ -0,0 +1,490 @@ +package com.ryg.dynamicload.internal; + +import java.util.List; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.FeatureInfo; +import android.content.pm.InstrumentationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionGroupInfo; +import android.content.pm.PermissionInfo; +import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.graphics.drawable.Drawable; + +/** + * 自定义PackageManager + * 当包名为插件本身时,从apk路径读取 + */ +public class DLPackageManager extends PackageManager { + + PackageManager mProxy; + DLPluginPackage mDlPackage; + + public DLPackageManager(DLPluginPackage dlPackage, PackageManager pm) { + mProxy = pm; + mDlPackage = dlPackage; + } + + @Override + public PackageInfo getPackageInfo(String packageName, int flags) + throws NameNotFoundException { + if(packageName.equals(mDlPackage.packageName)){ + PackageInfo pi = getPackageArchiveInfo(mDlPackage.dexPath, flags); + ApplicationInfo ai = pi.applicationInfo; + ai.sourceDir = mDlPackage.dexPath; + ai.publicSourceDir = mDlPackage.dexPath; + return pi; + }else{ + return mProxy.getPackageInfo(packageName, flags); + } + } + + @Override + public String[] currentToCanonicalPackageNames(String[] names) { + return mProxy.currentToCanonicalPackageNames(names); + } + + @Override + public String[] canonicalToCurrentPackageNames(String[] names) { + return mProxy.canonicalToCurrentPackageNames(names); + } + + @Override + public Intent getLaunchIntentForPackage(String packageName) { + return mProxy.getLaunchIntentForPackage(packageName); + } + + @Override + public int[] getPackageGids(String packageName) + throws NameNotFoundException { + PackageInfo info = getPackageInfo(packageName, 0); + return info.gids; + } + + @Override + public PermissionInfo getPermissionInfo(String name, int flags) + throws NameNotFoundException { + return mProxy.getPermissionInfo(name, flags); + } + + @Override + public List queryPermissionsByGroup(String group, int flags) + throws NameNotFoundException { + return mProxy.queryPermissionsByGroup(group, flags); + } + + @Override + public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) + throws NameNotFoundException { + return mProxy.getPermissionGroupInfo(name, flags); + } + + @Override + public List getAllPermissionGroups(int flags) { + return mProxy.getAllPermissionGroups(flags); + } + + @Override + public ApplicationInfo getApplicationInfo(String packageName, int flags) + throws NameNotFoundException { + PackageInfo pi = getPackageInfo(packageName, flags); + return pi.applicationInfo; + } + + @Override + public ActivityInfo getActivityInfo(ComponentName component, int flags) + throws NameNotFoundException { + PackageInfo pi = getPackageInfo(component.getPackageName(), flags); + ActivityInfo[] infos = pi.activities; + if(infos != null){ + for (ActivityInfo info : infos) { + if (info.name.equals(component.getClassName())) { + return info; + } + } + } + return null; + } + + @Override + public ActivityInfo getReceiverInfo(ComponentName component, int flags) + throws NameNotFoundException { + PackageInfo pi = getPackageInfo(component.getPackageName(), flags); + ActivityInfo[] infos = pi.activities; + if(infos != null){ + for (ActivityInfo info : infos) { + if (info.name.equals(component.getClassName())) { + return info; + } + } + } + return null; + } + + @Override + public ServiceInfo getServiceInfo(ComponentName component, int flags) + throws NameNotFoundException { + PackageInfo pi = getPackageInfo(component.getPackageName(), flags); + ServiceInfo[] sis = pi.services; + if(sis != null){ + for (ServiceInfo si : sis) { + if (si.name.equals(component.getClassName())) { + return si; + } + } + } + return null; + } + + @Override + public ProviderInfo getProviderInfo(ComponentName component, int flags) + throws NameNotFoundException { + PackageInfo pi = getPackageInfo(component.getPackageName(), flags); + ProviderInfo[] sis = pi.providers; + if(sis != null){ + for (ProviderInfo si : sis) { + if (si.name.equals(component.getClassName())) { + return si; + } + } + } + return null; + } + + @Override + public List getInstalledPackages(int flags) { + return mProxy.getInstalledPackages(flags); + } + + @Override + public List getPackagesHoldingPermissions( + String[] permissions, int flags) { + return mProxy.getPackagesHoldingPermissions(permissions, flags); + } + + @Override + public int checkPermission(String permName, String pkgName) { + if (pkgName.equals(mDlPackage.packageName)) { + PackageInfo pi = null; + try { + pi = getPackageInfo(pkgName, 0); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + if(pi != null){ + String[] pis = pi.requestedPermissions; + if(pis != null){ + for (String pei : pis) { + if(pei.equals(permName)){ + return PERMISSION_GRANTED; + } + } + } + } + return PERMISSION_DENIED; + } else { + return mProxy.checkPermission(permName, pkgName); + } + } + + @Override + public boolean addPermission(PermissionInfo info) { + return mProxy.addPermission(info); + } + + @Override + public boolean addPermissionAsync(PermissionInfo info) { + return mProxy.addPermissionAsync(info); + } + + @Override + public void removePermission(String name) { + mProxy.removePermission(name); + } + + @Override + public int checkSignatures(String pkg1, String pkg2) { + return mProxy.checkSignatures(pkg1, pkg2); + } + + @Override + public int checkSignatures(int uid1, int uid2) { + return mProxy.checkSignatures(uid1, uid2); + } + + @Override + public String[] getPackagesForUid(int uid) { + return mProxy.getPackagesForUid(uid); + } + + @Override + public String getNameForUid(int uid) { + return mProxy.getNameForUid(uid); + } + + @Override + public List getInstalledApplications(int flags) { + return mProxy.getInstalledApplications(flags); + } + + @Override + public String[] getSystemSharedLibraryNames() { + return mProxy.getSystemSharedLibraryNames(); + } + + @Override + public FeatureInfo[] getSystemAvailableFeatures() { + return mProxy.getSystemAvailableFeatures(); + } + + @Override + public boolean hasSystemFeature(String name) { + return mProxy.hasSystemFeature(name); + } + + @Override + public ResolveInfo resolveActivity(Intent intent, int flags) { + return mProxy.resolveActivity(intent, flags); + } + + @Override + public List queryIntentActivities(Intent intent, int flags) { + return mProxy.queryIntentActivities(intent, flags); + } + + @Override + public List queryIntentActivityOptions(ComponentName caller, + Intent[] specifics, Intent intent, int flags) { + return mProxy.queryIntentActivityOptions(caller, specifics, intent, flags); + } + + @Override + public List queryBroadcastReceivers(Intent intent, int flags) { + return mProxy.queryBroadcastReceivers(intent, flags); + } + + @Override + public ResolveInfo resolveService(Intent intent, int flags) { + return mProxy.resolveService(intent, flags); + } + + @Override + public List queryIntentServices(Intent intent, int flags) { + return mProxy.queryIntentServices(intent, flags); + } + + @Override + public List queryIntentContentProviders(Intent intent, + int flags) { + return mProxy.queryIntentContentProviders(intent, flags); + } + + @Override + public ProviderInfo resolveContentProvider(String name, int flags) { + return mProxy.resolveContentProvider(name, flags); + } + + @Override + public List queryContentProviders(String processName, + int uid, int flags) { + return mProxy.queryContentProviders(processName, uid, flags); + } + + @Override + public InstrumentationInfo getInstrumentationInfo(ComponentName className, + int flags) throws NameNotFoundException { + return mProxy.getInstrumentationInfo(className, flags); + } + + @Override + public List queryInstrumentation(String targetPackage, + int flags) { + return mProxy.queryInstrumentation(targetPackage, flags); + } + + @Override + public Drawable getDrawable(String packageName, int resid, + ApplicationInfo appInfo) { + return mProxy.getDrawable(packageName, resid, appInfo); + } + + @Override + public Drawable getActivityIcon(ComponentName activityName) + throws NameNotFoundException { + return mProxy.getActivityIcon(activityName); + } + + @Override + public Drawable getActivityIcon(Intent intent) throws NameNotFoundException { + return mProxy.getActivityIcon(intent); + } + + @Override + public Drawable getDefaultActivityIcon() { + return mProxy.getDefaultActivityIcon(); + } + + @Override + public Drawable getApplicationIcon(ApplicationInfo info) { + return mProxy.getApplicationIcon(info); + } + + @Override + public Drawable getApplicationIcon(String packageName) + throws NameNotFoundException { + return mProxy.getApplicationIcon(packageName); + } + + @Override + public Drawable getActivityLogo(ComponentName activityName) + throws NameNotFoundException { + return mProxy.getActivityLogo(activityName); + } + + @Override + public Drawable getActivityLogo(Intent intent) throws NameNotFoundException { + return mProxy.getActivityLogo(intent); + } + + @Override + public Drawable getApplicationLogo(ApplicationInfo info) { + return mProxy.getApplicationLogo(info); + } + + @Override + public Drawable getApplicationLogo(String packageName) + throws NameNotFoundException { + return mProxy.getApplicationLogo(packageName); + } + + @Override + public CharSequence getText(String packageName, int resid, + ApplicationInfo appInfo) { + return mProxy.getText(packageName, resid, appInfo); + } + + @Override + public XmlResourceParser getXml(String packageName, int resid, + ApplicationInfo appInfo) { + return mProxy.getXml(packageName, resid, appInfo); + } + + @Override + public CharSequence getApplicationLabel(ApplicationInfo info) { + return mProxy.getApplicationLabel(info); + } + + @Override + public Resources getResourcesForActivity(ComponentName activityName) + throws NameNotFoundException { + return mDlPackage.resources; + } + + @Override + public Resources getResourcesForApplication(ApplicationInfo app) + throws NameNotFoundException { + return mDlPackage.resources; + } + + @Override + public Resources getResourcesForApplication(String appPackageName) + throws NameNotFoundException { + return mDlPackage.resources; + } + + @Override + public void verifyPendingInstall(int id, int verificationCode) { + mProxy.verifyPendingInstall(id, verificationCode); + } + + @Override + public void extendVerificationTimeout(int id, + int verificationCodeAtTimeout, long millisecondsToDelay) { + mProxy.extendVerificationTimeout(id, verificationCodeAtTimeout, + millisecondsToDelay); + } + + @Override + public void setInstallerPackageName(String targetPackage, + String installerPackageName) { + mProxy.setInstallerPackageName(targetPackage, installerPackageName); + } + + @Override + public String getInstallerPackageName(String packageName) { + return mProxy.getInstallerPackageName(packageName); + } + + @Override + @Deprecated + public void addPackageToPreferred(String packageName) { + mProxy.addPackageToPreferred(packageName); + } + + @Override + @Deprecated + public void removePackageFromPreferred(String packageName) { + mProxy.removePackageFromPreferred(packageName); + } + + @Override + public List getPreferredPackages(int flags) { + return mProxy.getPreferredPackages(flags); + } + + @Override + @Deprecated + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity) { + mProxy.addPreferredActivity(filter, match, set, activity); + } + + @Override + public void clearPackagePreferredActivities(String packageName) { + mProxy.clearPackagePreferredActivities(packageName); + } + + @Override + public int getPreferredActivities(List outFilters, + List outActivities, String packageName) { + return mProxy.getPreferredActivities(outFilters, outActivities, + packageName); + } + + @Override + public void setComponentEnabledSetting(ComponentName componentName, + int newState, int flags) { + mProxy.setComponentEnabledSetting(componentName, newState, flags); + } + + @Override + public int getComponentEnabledSetting(ComponentName componentName) { + return mProxy.getComponentEnabledSetting(componentName); + } + + @Override + public void setApplicationEnabledSetting(String packageName, int newState, + int flags) { + mProxy.setApplicationEnabledSetting(packageName, newState, flags); + } + + @Override + public int getApplicationEnabledSetting(String packageName) { + return mProxy.getApplicationEnabledSetting(packageName); + } + + @Override + public boolean isSafeMode() { + return mProxy.isSafeMode(); + } + +} diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginManager.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginManager.java index 10a3fba..6d6e631 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginManager.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginManager.java @@ -35,6 +35,7 @@ import android.text.TextUtils; import android.util.Log; +import com.ryg.dynamicload.DLApplicationContext; import com.ryg.dynamicload.DLBasePluginActivity; import com.ryg.dynamicload.DLBasePluginFragmentActivity; import com.ryg.dynamicload.DLBasePluginService; @@ -130,6 +131,11 @@ public DLPluginPackage loadApk(final String dexPath, boolean hasSoLib) { } DLPluginPackage pluginPackage = preparePluginEnv(packageInfo, dexPath); + DLPackageManager dlPackageMgr = new DLPackageManager(pluginPackage, mContext.getPackageManager()); + DLApplicationContext dlAppCon = new DLApplicationContext(mContext.getApplicationContext(), pluginPackage); + pluginPackage.setDLPackageMgr(dlPackageMgr); + pluginPackage.setApplicationContext(dlAppCon); + if (hasSoLib) { copySoLib(dexPath); } @@ -154,7 +160,7 @@ private DLPluginPackage preparePluginEnv(PackageInfo packageInfo, String dexPath AssetManager assetManager = createAssetManager(dexPath); Resources resources = createResources(assetManager); // create pluginPackage - pluginPackage = new DLPluginPackage(dexClassLoader, resources, packageInfo); + pluginPackage = new DLPluginPackage(dexPath, dexClassLoader, resources, packageInfo); mPackagesHolder.put(packageInfo.packageName, pluginPackage); return pluginPackage; } @@ -419,6 +425,7 @@ private Class getProxyServiceClass(Class clazz) { private void performStartActivityForResult(Context context, DLIntent dlIntent, int requestCode) { Log.d(TAG, "launch " + dlIntent.getPluginClass()); + dlIntent.putExtra(DLConstants.INTENT_START_ACTI, true); if (context instanceof Activity) { ((Activity) context).startActivityForResult(dlIntent, requestCode); } else { diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginPackage.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginPackage.java index 537b7fb..b545757 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginPackage.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPluginPackage.java @@ -18,6 +18,8 @@ package com.ryg.dynamicload.internal; +import com.ryg.dynamicload.DLApplicationContext; + import android.content.pm.PackageInfo; import android.content.res.AssetManager; import android.content.res.Resources; @@ -38,17 +40,29 @@ public class DLPluginPackage { public AssetManager assetManager; public Resources resources; public PackageInfo packageInfo; + public String dexPath; + public DLPackageManager packageMgr; + public DLApplicationContext appContext; - public DLPluginPackage(DexClassLoader loader, Resources resources, - PackageInfo packageInfo) { - this.packageName = packageInfo.packageName; - this.classLoader = loader; - this.assetManager = resources.getAssets(); - this.resources = resources; - this.packageInfo = packageInfo; + public DLPluginPackage(String dexPath, DexClassLoader loader, + Resources resources, PackageInfo packageInfo) { + this.dexPath = dexPath; + this.packageName = packageInfo.packageName; + this.classLoader = loader; + this.assetManager = resources.getAssets(); + this.resources = resources; + this.packageInfo = packageInfo; - defaultActivity = parseDefaultActivityName(); - } + defaultActivity = parseDefaultActivityName(); + } + + public void setDLPackageMgr(DLPackageManager packageMgr){ + this.packageMgr = packageMgr; + } + + public void setApplicationContext(DLApplicationContext appContext){ + this.appContext = appContext; + } private final String parseDefaultActivityName() { if (packageInfo.activities != null && packageInfo.activities.length > 0) { diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLActivityProxy.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLActivityProxy.java index 6dec201..5a871be 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLActivityProxy.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLActivityProxy.java @@ -25,17 +25,21 @@ import android.content.res.Resources; import android.content.res.Resources.Theme; import android.os.Bundle; +import android.text.TextUtils; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager.LayoutParams; import com.ryg.dynamicload.internal.DLActivityPlugin; import com.ryg.dynamicload.internal.DLAttachable; +import com.ryg.dynamicload.internal.DLIntent; import com.ryg.dynamicload.internal.DLPluginManager; import com.ryg.dynamicload.internal.DLPluginPackage; import com.ryg.dynamicload.loader.DLActivityLoader; +import com.ryg.utils.DLConstants; public class DLActivityProxy extends Activity implements DLAttachable { @@ -180,5 +184,67 @@ public boolean onOptionsItemSelected(MenuItem item) { public ComponentName startService(Intent service) { return super.startService(service); } + + //--------add by xionghoumiao----------// + /** + * 插件apk直接调用上下文的startActivity即可调起activity + * @param intent + */ + @Override + public void startActivity(Intent intent) { + if (isStartSuperActi(intent)) { + super.startActivity(intent); + } else { + startPluginActivityForResult(intent, -1); + } + } + + @Override + public void startActivityForResult(Intent intent, int requestCode) { + if (isStartSuperActi(intent)) { + super.startActivityForResult(intent, requestCode); + } else { + startPluginActivityForResult(intent, requestCode); + } + } + + /** + * 是否启动真正的Activity + * 1.调用系统的界面action不能空 2.或者包含start_acti字段为true + * @param intent + * @return + */ + private boolean isStartSuperActi(Intent intent) { + boolean isStartSuperActi = (mRemoteActivity == null); + isStartSuperActi |= intent.getBooleanExtra( + DLConstants.INTENT_START_ACTI, false); + if (intent.hasExtra(DLConstants.INTENT_START_ACTI)) { + intent.removeExtra(DLConstants.INTENT_START_ACTI); + } + isStartSuperActi |= !TextUtils.isEmpty(intent.getAction()); + return isStartSuperActi; + } + + private int startPluginActivityForResult(Intent intent, int requestCode) { + DLIntent dlIntent = null; + if (intent instanceof DLIntent) { + dlIntent = (DLIntent) intent; + } else { + dlIntent = new DLIntent(mRemoteActivity.getPackageName(), intent); + } + if (dlIntent.getPluginPackage() == null) { + dlIntent.setPluginPackage(mRemoteActivity.getPackageName()); + } + DLPluginManager dlMgr = DLPluginManager.getInstance(this); + return dlMgr.startPluginActivityForResult(this, dlIntent, + requestCode); + } + + public void onClick(View view) { + if (mRemoteActivity != null) { + mRemoteActivity.onClick(view); + return; + } + } } diff --git a/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLFragmentActivityProxy.java b/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLFragmentActivityProxy.java index e3487fc..8bdc7b9 100644 --- a/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLFragmentActivityProxy.java +++ b/DynamicLoadApk/lib/src/com/ryg/dynamicload/proxy/DLFragmentActivityProxy.java @@ -24,16 +24,21 @@ import android.content.res.Resources.Theme; import android.os.Bundle; import android.support.v4.app.FragmentActivity; +import android.text.TextUtils; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager.LayoutParams; import com.ryg.dynamicload.internal.DLActivityPlugin; import com.ryg.dynamicload.internal.DLAttachable; +import com.ryg.dynamicload.internal.DLIntent; +import com.ryg.dynamicload.internal.DLPluginManager; import com.ryg.dynamicload.internal.DLPluginPackage; import com.ryg.dynamicload.loader.DLActivityLoader; +import com.ryg.utils.DLConstants; public class DLFragmentActivityProxy extends FragmentActivity implements DLAttachable { @@ -173,5 +178,61 @@ public boolean onOptionsItemSelected(MenuItem item) { mRemoteActivity.onOptionsItemSelected(item); return super.onOptionsItemSelected(item); } + + //--------add by xionghoumiao----------// + + @Override + public void startActivity(Intent intent) { + if (isStartSuperActi(intent)) { + super.startActivity(intent); + } else { + startPluginActivity(intent); + } + } + + @Override + public void startActivityForResult(Intent intent, int requestCode) { + if (isStartSuperActi(intent)) { + super.startActivityForResult(intent, requestCode); + } else { + startPluginActivityForResult(intent, requestCode); + } + } + + private boolean isStartSuperActi(Intent intent) { + boolean isStartSuperActi = (mRemoteActivity == null); + isStartSuperActi |= intent.getBooleanExtra( + DLConstants.INTENT_START_ACTI, false); + if (intent.hasExtra(DLConstants.INTENT_START_ACTI)) { + intent.removeExtra(DLConstants.INTENT_START_ACTI); + } + isStartSuperActi |= !TextUtils.isEmpty(intent.getAction()); + return isStartSuperActi; + } + + private int startPluginActivity(Intent dlIntent) { + return startPluginActivityForResult(dlIntent, -1); + } + + private int startPluginActivityForResult(Intent intent, int requestCode) { + DLIntent dlIntent = null; + if (intent instanceof DLIntent) { + dlIntent = (DLIntent) intent; + } else { + dlIntent = new DLIntent(mRemoteActivity.getPackageName(), intent); + } + if (dlIntent.getPluginPackage() == null) { + dlIntent.setPluginPackage(mRemoteActivity.getPackageName()); + } + DLPluginManager dlMgr = DLPluginManager.getInstance(this); + return dlMgr.startPluginActivityForResult(this, dlIntent, requestCode); + } + + public void onClick(View view) { + if (mRemoteActivity != null) { + mRemoteActivity.onClick(view); + return; + } + } } diff --git a/DynamicLoadApk/lib/src/com/ryg/utils/DLConstants.java b/DynamicLoadApk/lib/src/com/ryg/utils/DLConstants.java index 52c718c..3e7382b 100644 --- a/DynamicLoadApk/lib/src/com/ryg/utils/DLConstants.java +++ b/DynamicLoadApk/lib/src/com/ryg/utils/DLConstants.java @@ -51,5 +51,6 @@ public class DLConstants { */ public final static String INTENT_PLUGIN_PACKAGE = "dl_plugin_package"; public final static String INTENT_PLUGIN_CLASS = "dl_plugin_class"; + public final static String INTENT_START_ACTI = "dl_start_acti"; } diff --git a/DynamicLoadApk/lib/src/com/ryg/utils/SoLibManager.java b/DynamicLoadApk/lib/src/com/ryg/utils/SoLibManager.java index 04491a9..523fea2 100644 --- a/DynamicLoadApk/lib/src/com/ryg/utils/SoLibManager.java +++ b/DynamicLoadApk/lib/src/com/ryg/utils/SoLibManager.java @@ -172,7 +172,6 @@ private void writeSoFile2LibDir() throws IOException { is = mZipFile.getInputStream(mZipEntry); fos = new FileOutputStream(new File(sNativeLibDir, mSoFileName)); copy(is, fos); - mZipFile.close(); } /**