1.思路:
- 1.1 通过
getPackageArchiveInfo
方法获取sd卡的未安装的APK信息和Activity
- 1.2 获取到插件Activity的信息之后,通过反射得到插件Activity的实例
- 1.3 获取到插件Activity的实例后通过构造函数将宿主的上下文传递到插件APP
- 1.4 在反射调用插件activity的onCreate方法
2.宿主代码
package com.lazy.dex;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import dalvik.system.DexClassLoader;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity {
private String mClass;
String dexPath = Environment.getExternalStorageDirectory().toString() + File.separator + "a";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bt).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
launchTargetActivity();
}
});
}
@SuppressLint("NewApi")
protected void launchTargetActivity() {
//根据sd卡的路径获取未安装的apk的信息
PackageInfo packageInfo = getPackageManager().getPackageArchiveInfo(dexPath, 1);
if ((packageInfo.activities != null)
&& (packageInfo.activities.length > 0)) {
String activityName = packageInfo.activities[0].name;//获取插件中第一个activity
mClass = activityName;
launchTargetActivity(mClass);
}
}
@SuppressLint("NewApi")
protected void launchTargetActivity(final String className) {
Log.e("MainActivity", "start launchTargetActivity, className=" + className);
File dexOutputDir = this.getDir("dex", 0);
final String dexOutputPath = dexOutputDir.getAbsolutePath();
ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();
DexClassLoader dexClassLoader = new DexClassLoader(dexPath,
dexOutputPath, null, localClassLoader);
try {
Class<?> localClass = dexClassLoader.loadClass(className);//创建插件Activity的实例
//调用插件Activity的构造函数,将当前activity的上下文传递到插件activity中去
Constructor<?> localConstructor = localClass.getConstructor(new Class[]{Activity.class});
Object instance = localConstructor.newInstance(new Object[]{this});
Log.e("MainActivity", "instance = " + instance);
Method onCreate = localClass.getDeclaredMethod("onCreate", new Class[]{Bundle.class});
onCreate.setAccessible(true);
Bundle bundle = new Bundle();
onCreate.invoke(instance, bundle);//调用插件activity的onCreate方法
} catch (Exception e) {
Log.e("MainActivity", e.getMessage());
}
}
}
3.APP插件代码
package com.Company.Demo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
/**
* 项目名称:Demo1
* 类描述:
* 创建人:Administrator
* 创建时间:2017/9/20 17:24
* 修改人:Administrator
* 修改时间:2017/9/20 17:24
* 修改备注:
* 联系方式:906514731@qq.com
*/
public class TestActivity extends Activity implements OnClickListener {
/**
* 宿主的上下文引用
*/
private Activity otherActivity;
/**
* 无参构造函数
*/
public TestActivity() {
super();
}
/**
* 有参构造函数
* @param context
*/
public TestActivity(Activity context) {
super();
otherActivity = context;
Log.e("TestActivity", otherActivity.toString() );
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (otherActivity != null) {
// 使用TestHallActivity的上下文引用创建View并添加到根视图
Button button = new Button(otherActivity);
button.setText("我是插件TestActivity");
button.setOnClickListener(this);
LinearLayout root = new LinearLayout(otherActivity);
root.addView(button);
//使用宿主的上线文就不能使用插件的资源了
otherActivity.setContentView(root);
} else {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
/**
* 返回当前Activity的描述信息
* @return
*/
private String getRoomMessage() {
return "我是插件TestActivity";
}
@Override
public void onClick(View v) {
if (otherActivity != null) {
// Toast.makeText(this, "This is Room A!", Toast.LENGTH_SHORT).show();是不合适的调用
Toast.makeText(otherActivity, "我是插件TestActivity", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "我是插件TestActivity", Toast.LENGTH_SHORT).show();
}
}
}
网友评论
http://blog.csdn.net/jiangwei0910410003/article/details/48104455