第一部分,访问未安装应用的资源文件。
1,建立两个Project,取名一个叫new,一个old。
2,new项目生成apk文件拷贝到手机上面,注意不要拷贝到getFilesDir()指向的目录,apk一到那个目录就损坏,可以拷贝到它的父级目录;
3,接下来就是访问new.apk里面的资源文件了。
访问资源文件的代码如下:
try { /* */ 获取到AssetManager的实例,由于它的构造方法是隐藏的,不能直接new AssetManager manager=AssetManager.class.newInstance(); Class<? extends AssetManager> cls = manager.getClass(); //addAssetPath 方法是AssetManager 中很重要的方法,改方法的作用的 配置资源文件apk包 所在的路径,由于该方法在源码中是隐藏的,所以只能 通过反射方式来调用addAssetPath
Method method=cls.getDeclaredMethod("addAssetPath",String.class); method.setAccessible(true); method.invoke(manager,path);
//有了AssetManager对象我们就可以创建Resource 对象了,其余两个参数就用本地的即可;
Resources res=new Resources(manager,getResources().getDisplayMetrics(), getResources().getConfiguration());
//getIdentifier这个方法是根据资源文件名称,资源类型以及应用包名来获取资源文件所在应用的ID及R文件中的ID
//接下来就可以通过该ID,访问资源文件了。
int id=res.getIdentifier("app_name","string","anmin.calendar.xiaomi.apptwo"); String name=res.getString(id); Toast.makeText(MainActivity.this,name,Toast.LENGTH_LONG).show();} catch (Exception pE) { pE.printStackTrace();}
第二部分,启动未安装应用的Activity
1,装备好两个Project,分别叫做new,old;
2,将第一个new.apk,拷贝到手机上;
3,代码调用
被启动的activity代码,注意一定要调用带参数的构造,否则会报错,因为没有真正的上下文。
package anmin.calendar.xiaomi.apptwo; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; public class Main2Activity extends Activity { Activity mActivity; public Main2Activity() { super(); } public Main2Activity(Context pContext) { super(); this.mActivity= (Activity) pContext; } @Override protected void onCreate(Bundle savedInstanceState) { if (mActivity!=null){ TextView lTextView=new TextView(mActivity); ViewGroup.LayoutParams lParams=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lTextView.setLayoutParams(lParams); lTextView.setText("我是来自第三方启动的"); lTextView.setTextColor(Color.RED); lTextView.setTextSize(28); mActivity.setContentView(lTextView); mActivity.setContentView(lTextView); }else{ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); } Toast.makeText(this,"111",Toast.LENGTH_LONG).show(); } }
需要启动其他应用的Activity代码,通过反射的方式调用。
File f=new File(getFilesDir().getAbsolutePath()+File.separatorChar+"out"); if (!f.exists()){ f.mkdirs(); } File file=new File(path); String p=file.getParent()+File.separatorChar+"out"; File out=new File(p); if (!out.exists()){ out.mkdirs(); } DexClassLoader dexClassloader=new DexClassLoader(path,out.getAbsolutePath(),null, ClassLoader.getSystemClassLoader()); Class<?> cls = null; PackageInfo info=getPackageManager().getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES); try { cls = dexClassloader.loadClass(info.activities[1].name); Object ac = cls.newInstance(); Method method=cls.getDeclaredMethod("onCreate",new Class[]{Bundle.class}); method.setAccessible(true); method.invoke(ac,new Object[]{null}); } catch (ClassNotFoundException pE) { pE.printStackTrace(); } catch (NoSuchMethodException pE) { pE.printStackTrace(); } catch (InstantiationException pE) { pE.printStackTrace(); } catch (IllegalAccessException pE) { pE.printStackTrace(); } catch (InvocationTargetException pE) { pE.printStackTrace(); }