private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
// 1.创建ActivityClientRecord对象时没有对他的packageInfo赋值,所以它是null
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
}
// ...
Activity activity = null;
try {
// 2.非常重要!!这个ClassLoader保存于LoadedApk对象中,它是用来加载我们写的activity的加载器
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 3.用加载器来加载activity类,这个会根据不同的intent加载匹配的activity
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
// 4.这里的异常也是非常非常重要的!!!后面就根据这个提示找到突破口。。。
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
// 从这里就会执行到我们通常看到的activity的生命周期的onCreate里面
mInstrumentation.callActivityOnCreate(activity, r.state);
// 省略的是根据不同的状态执行生命周期
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
// ...
}
return activity;
}
public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
int flags) {
// 为true
boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
boolean securityViolation = includeCode && ai.uid != 0
&& ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
: true);
// ...
// includeCode为true
// classloader为null!!!
return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
synchronized (mPackages) {
WeakReference<loadedapk> ref;
if (includeCode) {
// includeCode为true
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null && !packageInfo.mResources.getAssets().isUpToDate())) {
if (localLOGV) // ...
// packageInfo为null,创建一个LoadedApk,并且添加到mPackages里面
packageInfo = new LoadedApk(this, aInfo, compatInfo, this, baseLoader, securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo. ) != 0);
if (includeCode) {
mPackages.put(aInfo.packageName, new WeakReference<loadedapk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName, new WeakReference<loadedapk>(packageInfo));
}
}
return packageInfo;
}
}</loadedapk></loadedapk></loadedapk>
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader != null) {
return mClassLoader;
}
// ...
// 创建加载器,创建默认的加载器
// zip为Apk的路径,libraryPath也就是JNI的路径
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, libraryPath, mBaseClassLoader);
initializeJavaContextClassLoader();
StrictMode.setThreadPolicy(oldPolicy);
} else {
if (mBaseClassLoader == null) {
mClassLoader = ClassLoader.getSystemClassLoader();
} else {
mClassLoader = mBaseClassLoader;
}
}
return mClassLoader;
}
}
public Activity newActivity(ClassLoader cl, String className,Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载到宿主程序中之后,这个R.layout.activity_main就是宿主程序中的R.layout.activity_main了
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Toast.makeText(this,"onStart", 0).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this,"onDestroy", 0).show();
}
}
private Button btn;
private Button btn1;
DexClassLoader loader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
btn1 = (Button) findViewById(R.id.btn1);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Class activity = null;
String dexPath = "/PluginActivity.apk";
loader = new DexClassLoader(dexPath, MainActivity.this.getApplicationInfo().dataDir, null, getClass().getClassLoader());
try {
activity = loader.loadClass("plugin.dl.pluginactivity.MainActivity");
}catch (ClassNotFoundException e) {
Log.i("MainActivity", "ClassNotFoundException");
}
Intent intent = new Intent(MainActivity.this, activity);
MainActivity.this.startActivity(intent);
}
});
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
MainActivity.this.startActivity(intent);
}
});
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{host.dl.hostactivity/plugin.dl.pluginactivity.MainActivity}: java.lang.ClassNotFoundException: plugin.dl.pluginactivity.MainActivity
private void replaceClassLoader(DexClassLoader loader) {
try {
Class clazz_Ath = Class.forName("android.app.ActivityThread");
Class clazz_LApk = Class.forName("android.app.LoadedApk");
Object currentActivityThread = clazz_Ath.getMethod("currentActivityThread").invoke(null);
Field field1 = clazz_Ath.getDeclaredField("mPackages");
field1.setAccessible(true);
Map mPackages = (Map) field1.get(currentActivitead);
String packageName = MainActivity.this.getPackageName();
WeakReference ref = (WeakReference) mPackages.get(packageName);
Field field2 = clazz_LApk.getDeclaredField("mClassLoader");
field2.setAccessible(true);
field2.set(ref.get(), loader);
} catch (Exception e) {
e.printStackTrace();
}
}
public class MainActivity2 extends Activity {
private static View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载到宿主程序中之后,这个R.layout.activity_main就是宿主程序中的R.layout.activity_main了
// setContentView(R.layout.activity_main);
if (view != null)
setContentView(view);
}
@Override
protected void onStart() {
super.onStart();
Toast.makeText(this,"onStart", 0).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this,"onDestroy", 0).show();
}
private static void setLayout(View v){
view = v;
}
}
Class<!--?--> layout = loader.loadClass("plugin.dl.pluginactivity.R$layout");
Field field = layout.getField("activity_main");
Integer obj = (Integer) field.get(null);
// 使用包含插件APK的Resources对象来获取这个布局才能正确获取插件中定义的界面效果
//View view = LayoutInflater.from(MainActivity.this).inflate(resources.getLayout(obj),null);
// 或者这样,但一定要重写getResources方法,才能这样写
View view = LayoutInflater.from(MainActivity.this).inflate(obj, null);
Method method = activity.getDeclaredMethod("setLayout", View.class);
method.setAccessible(true);
method.invoke(activity, view);
public class MainActivity extends Activity {
private Resources resources;
protected AssetManager assetManager;
private Button btn;
private Button btn1;
DexClassLoader loader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
btn1 = (Button) findViewById(R.id.btn1);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String dexPath = "/PluginActivity.apk";
loader = new DexClassLoader(dexPath, MainActivity.this.getApplicationInfo().dataDir, null, getClass().getClassLoader());
Class<!--?--> activity = null;
Class<!--?--> layout = null;
try {
activity = loader.loadClass("plugin.dl.pluginactivity.MainActivity");
layout = loader.loadClass("plugin.dl.pluginactivity.R$layout");
}catch (ClassNotFoundException e) {
Log.i("MainActivity", "ClassNotFoundException");
}
replaceClassLoader(loader);
loadRes(dexPath);
try {
Field field = layout.getField("activity_main");
Integer obj = (Integer) field.get(null);
// 使用包含插件APK的Resources对象来获取这个布局才能正确获取插件中定义的界面效果
View view = LayoutInflater.from(MainActivity.this).inflate(resources.getLayout(obj),null);
// 或者这样,但一定要重写getResources方法,才能这样写
// View view = LayoutInflater.from(MainActivity.this).inflate(obj, null);
Method method = activity.getDeclaredMethod("setLayout", View.class);
method.setAccessible(true);
method.invoke(activity, view);
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(MainActivity.this, activity);
MainActivity.this.startActivity(intent);
}
});
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
MainActivity.this.startActivity(intent);
}
});
}
public void loadRes(String path){
try {
assetManager = AssetManager.class.newInstance();
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, path);
} catch (Exception e) {
}
resources = new Resources(assetManager, super.getResources().getDisplayMetrics(), super.getResources().getConfiguration());
// 也可以根据资源获取主题
}
private void replaceClassLoader(DexClassLoader loader){
try {
Class clazz_Ath = Class.forName("android.app.ActivityThread");
Class clazz_LApk = Class.forName("android.app.LoadedApk");
Object currentActivityThread = clazz_Ath.getMethod("currentActivityThread").invoke(null);
Field field1 = clazz_Ath.getDeclaredField("mPackages");
field1.setAccessible(true);
Map mPackages = (Map)field1.get(currentActivityThread);
String packageName = MainActivity.this.getPackageName();
WeakReference ref = (WeakReference) mPackages.get(packageName);
Field field2 = clazz_LApk.getDeclaredField("mClassLoader");
field2.setAccessible(true);
field2.set(ref.get(), loader);
} catch (Exception e){
System.out.println("-------------------------------------" + "click");
e.printStackTrace();
}
}
@Override
public Resources getResources() {
return resources == null ? super.getResources() : resources;
}
@Override
public AssetManager getAssets() {
return assetManager == null ? super.getAssets() : assetManager;
}
}
public class MainActivity extends Activity{
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.this.startActivity(new Intent(MainActivity.this, ProxyActivity.class));
}
});
}
}
public class ProxyActivity extends Activity{
private DexClassLoader loader;
private Activity activity;
private Class<!--?--> clazz = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loader = new DexClassLoader("/Plugin.apk", getApplicationInfo().dataDir, null, getClass().getClassLoader());
try {
clazz = loader.loadClass("com.dl.plugin.MainActivity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 设置插件activity的代理
try {
Method setProxy = clazz.getDeclaredMethod("setProxy", Activity.class);
setProxy.setAccessible(true);
activity = (Activity)clazz.newInstance();
setProxy.invoke(activity, this);
Method onCreate = clazz.getDeclaredMethod("onCreate", Bundle.class);
onCreate.setAccessible(true);
onCreate.invoke(activity, savedInstanceState);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onStart() {
super.onStart();
// 调用插件activity的onStart方法
Method onStart = null;
try {
onStart = clazz.getDeclaredMethod("onStart");
onStart.setAccessible(true);
onStart.invoke(activity);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onStart();
// 调用插件activity的onDestroy方法
Method onDestroy = null;
try {
onDestroy = clazz.getDeclaredMethod("onDestroy");
onDestroy.setAccessible(true);
onDestroy.invoke(activity);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MainActivity extends Activity {
private Activity proxyActivity;
public void setProxy(Activity proxyActivity) {
this.proxyActivity = proxyActivity;
}
// 里面的所有操作都由代理activity来操作
@Override
protected void onCreate(Bundle savedInstanceState) {
TextView tv = new TextView(proxyActivity);
tv.setText("插件Activity");
proxyActivity.setContentView(tv,new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
@Override
protected void onStart() {
Toast.makeText(proxyActivity, "插件onStart", 0).show();
}
@Override
protected void onDestroy() {
Toast.makeText(proxyActivity, "插件onDestroy", 0).show();
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有