From fbcfa3c44a745320cca0368a56bdf6360bd40560 Mon Sep 17 00:00:00 2001 From: xionghoumiao Date: Mon, 16 Nov 2015 19:16:23 +0800 Subject: [PATCH] 1.add DLApplicationContext is used to single instance for plugin apk 2.add DLPackageManager is used to acquire androidmanifest data for plugin apk 3.modify ProxyActivity startActivity method to adapter to plugin apk and normal apk 4.fix SoLibManager close zipfile bug 5.add some method on BasePluginActivity to adapter to plugin apk --- .../ryg/dynamicload/DLApplicationContext.java | 84 +++ .../ryg/dynamicload/DLBasePluginActivity.java | 156 +++--- .../DLBasePluginFragmentActivity.java | 218 +++++--- .../internal/DLActivityPlugin.java | 12 + .../ryg/dynamicload/internal/DLIntent.java | 11 + .../internal/DLPackageManager.java | 490 ++++++++++++++++++ .../dynamicload/internal/DLPluginManager.java | 9 +- .../dynamicload/internal/DLPluginPackage.java | 32 +- .../dynamicload/proxy/DLActivityProxy.java | 66 +++ .../proxy/DLFragmentActivityProxy.java | 61 +++ .../lib/src/com/ryg/utils/DLConstants.java | 1 + .../lib/src/com/ryg/utils/SoLibManager.java | 1 - 12 files changed, 1000 insertions(+), 141 deletions(-) create mode 100644 DynamicLoadApk/lib/src/com/ryg/dynamicload/DLApplicationContext.java create mode 100644 DynamicLoadApk/lib/src/com/ryg/dynamicload/internal/DLPackageManager.java 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(); } /**