我已经完成了超过65 000种方法的JMonkey
个应用。我想在android
上运行它。所以,我使用multi dex选项来构建apk。然后我动态加载第二个.dex文件。
我将第二个.dex文件存储在一个jar中,位于apk的资产目录中。
这是我的Android主要活动代码:
public class MainActivityStart extends Activity {
private static final String SECONDARY_DEX_NAME = "classes2.jar";
/**
* Buffer size for file copying. While 8kb is used in this sample, you may
* want to tweak it based on actual size of the secondary dex file involved.
*/
private static final int BUF_SIZE = 8 * 1024;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadSecondaryDex();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
private void loadSecondaryDex() {
// Before the secondary dex file can be processed by the DexClassLoader,
// it has to be first copied from asset resource to a storage location.
final File dexInternalStoragePath = new File(getDir("dex",
Context.MODE_PRIVATE), SECONDARY_DEX_NAME);
prepareDex(dexInternalStoragePath);
final File dexOutputDir = getDir("outdex", 0);
DexClassLoader cl = new DexClassLoader(
dexInternalStoragePath.getAbsolutePath(),
dexOutputDir.getAbsolutePath(), null, getClassLoader()) {
@Override
public Class<?> loadClass(final String className)
throws ClassNotFoundException {
return super.loadClass(className);
}
};
}
// File I/O code to copy the secondary dex file from asset resource to
// internal storage.
private void prepareDex(final File dexInternalStoragePath) {
BufferedInputStream bis = null;
OutputStream dexWriter = null;
try {
bis = new BufferedInputStream(getAssets().open(SECONDARY_DEX_NAME));
dexWriter = new BufferedOutputStream(new FileOutputStream(
dexInternalStoragePath));
final byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
dexWriter.write(buf, 0, len);
}
dexWriter.close();
bis.close();
// return true;
} catch (final IOException e) {
if (dexWriter != null) {
try {
dexWriter.close();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
}
// return false;
}
}
}
如您所见,当动态类加载完成后,我切换到Jmonkey Activity。这个扩展了AndroidHarness类适用于Android的JME应用程序。
以下是代码:
public class MainActivity extends AndroidHarness {
public MainActivity() {
// Set the application class to run
appClass = "mygame.Main";
// Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems
eglConfigType = ConfigType.LEGACY;
// Exit Dialog title & message
exitDialogTitle = "Quit game?";
exitDialogMessage = "Do you really want to quit the game?";
// Choose screen orientation
screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
// Invert the MouseEvents X (default = true)
mouseEventsInvertX = true;
// Invert the MouseEvents Y (default = true)
mouseEventsInvertY = true;
}
}
运行这个给我一个很好的例外:
07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):SEVERE类mygame.Main init失败 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):java.lang.ClassNotFoundException:mygame.Main 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.Class.classForName(Native Method) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.Class.forName(Class.java:251) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.Class.forName(Class.java:216) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at com.jme3.app.AndroidHarness.onCreate(AndroidHarness.java:223) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.Activity.performCreate(Activity.java:5231) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.ActivityThread.access $ 800(ActivityThread.java:135) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1196) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.os.Handler.dispatchMessage(Handler.java:102) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.os.Looper.loop(Looper.java:136) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):在android.app.ActivityThread.main(ActivityThread.java:5001) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.reflect.Method.invokeNative(Native Method) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.reflect.Method.invoke(Method.java:515) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:785) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at dalvik.system.NativeStart.main(Native Method) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):引起:java.lang.NoClassDefFoundError:mygame / Main 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):... 18更多 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):引起:java.lang.ClassNotFoundException:找不到类&#34; mygame.Main&#34; on path:DexPathList [[zip file&#34; /data/app/com.example.j4a-1.apk"],nativeLibraryDirectories = [/ data / app-lib / com.example.j4a-1,/ vendor / lib,/ system / lib]] 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.ClassLoader.loadClass(ClassLoader.java:497) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):at java.lang.ClassLoader.loadClass(ClassLoader.java:457) 07-28 10:59:21.645:E / com.jme3.app.AndroidHarness(3788):... 18更多
所以,找不到主要课程......你们有没有想过要做的伎俩?
另外一个问题: 我无法直接在扩展AndroidHarness的MainActivity类中访问Activity类提供的方法,例如getDir(); getAssets();或者更重要的是,getContext(); 它将永远返回NPE ......
如果我能这样做,我将能够在这个类中进行动态加载并通过反射调用mygame.Main类,这可能很棒。所以,如果你们有解决方案......先谢谢你们!
答案 0 :(得分:0)
您的问题似乎与ClassLoader有关。
当您调用Class.forName(MyGame)时,VM会尝试从调用ClassLoader(与包含调用Class.forName的类关联的ClassLoader)中查找该类。 根据你的帖子,我认为你的类还没有被加载,或者已被另一个ClassLoader加载。
在调用Class.forName之前,必须确保已经加载了要查找的类,并且已经加载了与加载调用类的类或其父类之一相同的ClassLoader。