在网上找到实例后,自己不断的扩充这个实例,但是这样安装适合门户网站的开发和一些简单的外接apk(这个apk一般只有一个activity),因为此apk的上下文是主apk中传过去的,所以很多资源都要使用主apk的,除非是在次apk中自己定义一些资源(比如布局文件要么在主apk中定义好,下面有实例,要么就在次apk中自己用java写控件加载,还比如,加载资源文件要么在主apk中定义好直接调用,要么自己在类中根据当前的配置语言写中英文),这里的上下文传递过来后就不能再调用其他的activity了。
具体代码如下
主apk工程如下:
package com.android.reflect.main;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import dalvik.system.DexClassLoader;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private Class mLoadClass=null;
private Object mLoadIstance=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bundle paramBundle = new Bundle();
paramBundle.putBoolean("KEY_START_FROM_OTHER_ACTIVITY",true);
//String dexpath = "/sdcard/TestB.apk";
String dexpath = "/sdcard/TestB.apk";
String dexoutputpath = "/sdcard/";
LoadAPK(paramBundle, dexpath, dexoutputpath);
}
});
}
public void LoadAPK(Bundle paramBundle, String dexpath, String dexoutputpath) {
ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();
DexClassLoader localDexClassLoader = new DexClassLoader(dexpath,
dexoutputpath, null, localClassLoader);
try {
PackageInfo plocalObject = getPackageManager()
.getPackageArchiveInfo(dexpath, 1);
if ((plocalObject.activities != null)
&& (plocalObject.activities.length > 0)) {
String activityname = plocalObject.activities[0].name;
Log.d(TAG, "activityname = " + activityname);
mLoadClass = localDexClassLoader.loadClass(activityname);
Constructor localConstructor = mLoadClass
.getConstructor(new Class[] {});
mLoadIstance = localConstructor.newInstance(new Object[] {});
Log.d(TAG, "instance = " + mLoadIstance);
Method localMethodSetActivity = mLoadClass.getDeclaredMethod(
"setActivity", new Class[] { Activity.class });
localMethodSetActivity.setAccessible(true);
localMethodSetActivity.invoke(mLoadIstance, new Object[] { this });
Method methodonCreate = mLoadClass.getDeclaredMethod(
"onCreate", new Class[] { Bundle.class });
methodonCreate.setAccessible(true);
methodonCreate.invoke(mLoadIstance, new Object[] { paramBundle });
}
return;
} catch (Exception ex) {
ex.printStackTrace();
}
}
/*public ApplicationInfo getApplicationInfo(Uri packageURI) {
final String archiveFilePath = packageURI.getPath();
PackageParser packageParser = new PackageParser(archiveFilePath);
File sourceFile = new File(archiveFilePath);
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
if (pkg == null) {
return null;
}
return pkg.applicationInfo;
} */
@Override
protected void onStart() {
super.onStart();
try {
Method method = mLoadClass.getDeclaredMethod(
"onStart");
method.setAccessible(true);
method.invoke(mLoadIstance);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
try {
Method method = mLoadClass.getDeclaredMethod(
"onResume");
method.setAccessible(true);
method.invoke(mLoadIstance);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onPause() {
super.onPause();
try {
Method method =mLoadClass.getDeclaredMethod(
"onPause");
method.setAccessible(true);
method.invoke(mLoadIstance);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
try {
Method method = mLoadClass.getDeclaredMethod(
"onStop");
method.setAccessible(true);
method.invoke(mLoadIstance);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
Method method = mLoadClass.getDeclaredMethod(
"onDestroy");
method.setAccessible(true);
method.invoke(mLoadIstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
22222222222222222222222222222
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.reflect.main"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="com.android.reflect.main.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
333333333333
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:text="Start Activity B"
android:layout_width="wrap_content"
android:id="@+id/btn"
android:layout_height="wrap_content">
</Button>
<Button android:text="Start Activity B"
android:layout_width="wrap_content"
android:id="@+id/btna"
android:layout_height="wrap_content">
</Button>
<Button android:text="Start Activity B"
android:layout_width="wrap_content"
android:id="@+id/btnb"
android:layout_height="wrap_content">
</Button>
<Button android:text="Start Activity B"
android:layout_width="wrap_content"
android:id="@+id/btnc"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
444444444
mainlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/main"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="cccccccccccccccc"
android:background="@drawable/icon"
/>
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="cccccccccccccccc"
android:background="@drawable/icon"
android:id="@+id/btnclick"
/>
</LinearLayout>
接下来是次apk的代码如下:
package com.android.reflect;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
public class TestBActivity extends Activity {
private static final String TAG = "TestBActivity";
private Activity otherActivity;
private SurfaceView mSurfaceView;
private LinearLayout rootLayout;
private TextView mTextView;
private View mMainView;
private void initView(){
LinearLayout.LayoutParams paramLayoutParams=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
rootLayout = new LinearLayout(this.otherActivity);
rootLayout.setLayoutParams(paramLayoutParams);
mTextView = new TextView(this.otherActivity);
mTextView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mTextView.setTextColor(Color.GREEN);
mTextView.setTextSize(30);
mTextView.setText("cccccccccc");
mTextView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {//getResource is mainActivity resoures
//right Toast.makeText(otherActivity,otherActivity.getResources().getString(R.string.app_name),Toast.LENGTH_LONG).show();
//error Toast.makeText(otherActivity,TestBActivity.this.getResources().getString(R.string.app_name),Toast.LENGTH_LONG).show();
/* Intent intent=new Intent();
intent.setAction("aa");
startActivity(intent);*/
}
});
rootLayout.addView(mTextView);
int layoutId=otherActivity.getResources().getIdentifier("mainlayout", "layout","com.android.reflect.main");
mMainView=otherActivity.getLayoutInflater().inflate(layoutId, null);
int btnclick=otherActivity.getResources().getIdentifier("btnclick", "id","com.android.reflect.main");
Button mBtn=(Button)mMainView.findViewById(btnclick);
mBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(otherActivity,otherActivity.getResources().getString(R.string.app_name),Toast.LENGTH_LONG).show();
}
});
mSurfaceView=new TBSurfaceView(this.otherActivity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
boolean b = false;
if (savedInstanceState != null) {
b = savedInstanceState.getBoolean("KEY_START_FROM_OTHER_ACTIVITY", false);
if (b) {
initView();
//this.otherActivity.setContentView(mSurfaceView);
//this.otherActivity.setContentView(rootLayout);
this.otherActivity.setContentView(mMainView);
}
}
Log.i(TAG, "==onCreate===b="+b);
if (!b) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
setContentView(new TBSurfaceView(this));
}
}
public void setActivity(Activity paramActivity) {
Log.d(TAG, "setActivity..." + paramActivity);
this.otherActivity = paramActivity;
}
}
2222222222222222222222
package com.android.reflect;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class TBSurfaceView extends SurfaceView implements Callback, Runnable {
private SurfaceHolder sfh;
private Thread th;
private Canvas canvas;
private Paint paint;
public TBSurfaceView(Context context) {
super(context);
th = new Thread(this);
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
this.setKeepScreenOn(true);
}
public void surfaceCreated(SurfaceHolder holder) {
th.start();
}
private void draw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.WHITE);
canvas.drawText("Time: " + System.currentTimeMillis(), 100,
100, paint);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (canvas != null) {
sfh.unlockCanvasAndPost(canvas);
}
}
}
public void run() {
while (true) {
draw();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
333333333333
package com.android.reflect;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
}
}
4444444444444
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.reflect"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".TestBActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="aa" />
</intent-filter>
</activity>
</application>
</manifest>
5555555
clayout。xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/main"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="cccccccccccccccc"
android:background="@drawable/icon"
/>
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="cccccccccccccccc"
android:background="@drawable/icon"/>
</LinearLayout>
66666666666
main。xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>