diff options
Diffstat (limited to 'src')
4 files changed, 117 insertions, 32 deletions
diff --git a/src/java/jogamp/android/launcher/ActivityLauncher.java b/src/java/jogamp/android/launcher/ActivityLauncher.java index bd7c723..6620b59 100644 --- a/src/java/jogamp/android/launcher/ActivityLauncher.java +++ b/src/java/jogamp/android/launcher/ActivityLauncher.java @@ -93,24 +93,24 @@ public class ActivityLauncher extends Activity { @Override public void onStart() { Log.d(TAG, "onStart - S"); - callMethod(activityObject, mOnStart); super.onStart(); + callMethod(activityObject, mOnStart); Log.d(TAG, "onStart - X"); } @Override public void onRestart() { Log.d(TAG, "onRestart - S"); - callMethod(activityObject, mOnRestart); super.onRestart(); + callMethod(activityObject, mOnRestart); Log.d(TAG, "onRestart - X"); } @Override public void onResume() { Log.d(TAG, "onResume - S"); - callMethod(activityObject, mOnResume); super.onResume(); + callMethod(activityObject, mOnResume); Log.d(TAG, "onResume - X"); } diff --git a/src/java/jogamp/android/launcher/LauncherUtil.java b/src/java/jogamp/android/launcher/LauncherUtil.java index 41bbf52..b68768b 100644 --- a/src/java/jogamp/android/launcher/LauncherUtil.java +++ b/src/java/jogamp/android/launcher/LauncherUtil.java @@ -67,9 +67,11 @@ public class LauncherUtil { static final String PKG = "pkg"; + static final String ARG = "arg"; + public static abstract class BaseActivityLauncher extends Activity { final OrderedProperties props = new OrderedProperties(); - + final ArrayList<String> args = new ArrayList<String>(); /** * Returns the default {@link LauncherUtil#LAUNCH_ACTIVITY_NORMAL} action. * <p> @@ -86,6 +88,14 @@ public class LauncherUtil { */ public final OrderedProperties getProperties() { return props; } + /** + * Returns the commandline arguments, which are being propagated to the target activity. + * <p> + * Maybe be used to set custom commandline arguments. + * </p> + */ + public final ArrayList<String> getArguments() { return args; } + /** Custom initialization hook which can be overriden to setup data, e.g. fill the properties retrieved by {@link #getProperties()}. */ public void init() { } @@ -108,6 +118,7 @@ public class LauncherUtil { data.setActivityName(getActivityName()); data.addAllPackages(getPackages()); data.addAllProperties(props); + data.addAllArguments(args); final Intent intent = LauncherUtil.getIntent(getAction(), data); Log.d(getClass().getSimpleName(), "Launching Activity: "+intent); @@ -127,6 +138,9 @@ public class LauncherUtil { if(key.equals(PKG)) { throw new IllegalArgumentException("Illegal property key, '"+PKG+"' is reserved"); } + if(key.equals(ARG)) { + throw new IllegalArgumentException("Illegal property key, '"+ARG+"' is reserved"); + } final String oval = map.put(key, value); if(null != oval) { map.put(key, oval); // restore @@ -175,6 +189,7 @@ public class LauncherUtil { String activityName = null; ArrayList<String> packages = new ArrayList<String>(); OrderedProperties properties = new OrderedProperties(); + ArrayList<String> arguments = new ArrayList<String>(); public final void setActivityName(String name) { activityName = name; } public final String getActivityName() { return activityName; } @@ -201,7 +216,13 @@ public class LauncherUtil { } public final String getProperty(String key) { return properties.getProperty(key); } public final OrderedProperties getProperties() { return properties; } - public final List<String> getPropertyKeys() { return properties.getPropertyKeys(); } + public final List<String> getPropertyKeys() { return properties.getPropertyKeys(); } + + public final void addArgument(String arg) { arguments.add(arg); } + public final void addAllArguments(List<String> args) { + arguments.addAll(args); + } + public final ArrayList<String> getArguments() { return arguments; } public final Uri getUri() { StringBuilder sb = new StringBuilder(); @@ -217,15 +238,23 @@ public class LauncherUtil { needsSep = true; } } - Iterator<String> argKeys = properties.keyList.iterator(); - while(argKeys.hasNext()) { + Iterator<String> propKeys = properties.keyList.iterator(); + while(propKeys.hasNext()) { if(needsSep) { sb.append(AMPER); } - final String key = argKeys.next(); + final String key = propKeys.next(); sb.append(key).append(ASSIG).append(properties.map.get(key)); needsSep = true; } + Iterator<String> args = arguments.iterator(); + while(args.hasNext()) { + if(needsSep) { + sb.append(AMPER); + } + sb.append(ARG).append(ASSIG).append(args.next()); + needsSep = true; + } return Uri.parse(sb.toString()); } @@ -255,7 +284,7 @@ public class LauncherUtil { int q_b = q_e + 1; // next term q_e = q.indexOf(AMPER, q_b); if(0 == q_e) { - // single seperator + // single separator continue; } if(0 > q_e) { @@ -274,13 +303,18 @@ public class LauncherUtil { throw new IllegalArgumentException("Empty package name: part <"+part+">, query <"+q+"> of "+uri); } data.addPackage(v); + } else if(k.equals(ARG)) { + if(v.length()==0) { + throw new IllegalArgumentException("Empty argument name: part <"+part+">, query <"+q+"> of "+uri); + } + data.addArgument(v); } else { data.setProperty(k, v); } } else { // property key only - if(part.equals(PKG)) { - throw new IllegalArgumentException("Empty package name: part <"+part+">, query <"+q+"> of "+uri); + if( part.equals(PKG) || part.equals(ARG) ) { + throw new IllegalArgumentException("Reserved key <"+part+"> in query <"+q+"> of "+uri); } data.setProperty(part, EMPTY); } @@ -306,21 +340,31 @@ public class LauncherUtil { args = new String[] { SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1&"+PKG+"=javax.pack2&"+PKG+"=com.jogamp.pack3&jogamp.common.debug=true&com.jogamp.test=false", SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1&jogamp.common.debug=true&com.jogamp.test=false", - SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1" + SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1", + SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1&"+PKG+"=javax.pack2&"+PKG+"=com.jogamp.pack3&jogamp.common.debug=true&com.jogamp.test=false&"+ARG+"=arg1&"+ARG+"=arg2=arg2value&"+ARG+"=arg3", + SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1&jogamp.common.debug=true&com.jogamp.test=false&"+ARG+"=arg1&"+ARG+"=arg2=arg2value&"+ARG+"=arg3", + SCHEME+"://"+HOST+"/com.jogamp.TestActivity?"+PKG+"=jogamp.pack1&"+ARG+"=arg1&"+ARG+"=arg2=arg2value&"+ARG+"=arg3" }; } + int errors = 0; for(int i=0; i<args.length; i++) { String uri_s = args[i]; Uri uri0 = Uri.parse(uri_s); DataSet data = DataSet.create(uri0); if(null == data) { + errors++; System.err.println("Error: NULL JogAmpLauncherUtil: <"+uri_s+"> -> "+uri0+" -> NULL"); - } - Uri uri1 = data.getUri(); - if(!uri0.equals(uri1)) { - System.err.println("Error: Not equal: <"+uri_s+"> -> "+uri0+" -> "+uri1); + } else { + Uri uri1 = data.getUri(); + if(!uri0.equals(uri1)) { + errors++; + System.err.println("Error: Not equal: <"+uri_s+"> -> "+uri0+" -> "+uri1); + } else { + System.err.println("OK: "+uri1); + } } } + System.err.println("LauncherUtil Self Test: Errors: "+errors); } } diff --git a/src/java/jogamp/android/launcher/MainLauncher.java b/src/java/jogamp/android/launcher/MainLauncher.java index 12dafb7..b0cef60 100644 --- a/src/java/jogamp/android/launcher/MainLauncher.java +++ b/src/java/jogamp/android/launcher/MainLauncher.java @@ -31,6 +31,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import android.app.Activity; import android.net.Uri; @@ -41,7 +42,8 @@ public class MainLauncher extends Activity { static final String TAG = "JogAmp-MainLauncher"; // private static final String[] frameworkAPKs = { "/system/framework/core-junit.jar", "/data/projects/gluegen/make/lib/ant-junit-all.apk" }; - private static final String[] frameworkAPKs = { "/data/projects/gluegen/make/lib/ant-junit-all.apk" }; + // private static final String[] frameworkAPKs = { "/data/projects/gluegen/make/lib/ant-junit-all.apk" }; + private static final String[] frameworkAPKs = { "/sdcard/ant-junit-all.apk" }; LauncherUtil.DataSet data = null; @@ -66,7 +68,7 @@ public class MainLauncher extends Activity { if(null != cl) { try { staticContextClazz = Class.forName("jogamp.common.os.android.StaticContext", true, cl); - mStaticContextInit = staticContextClazz.getMethod("init", android.content.Context.class); + mStaticContextInit = staticContextClazz.getMethod("init", android.content.Context.class, android.view.ViewGroup.class); mStaticContextClear = staticContextClazz.getMethod("clear"); mainClazz = Class.forName(data.getActivityName(), true, cl); @@ -79,17 +81,21 @@ public class MainLauncher extends Activity { } } - if( null == mStaticContextInit || null == mStaticContextClear || - null == mainClazzMain ) { + if( null == mStaticContextInit || null == mStaticContextClear || null == mainClazzMain ) { RuntimeException e = new RuntimeException("XXX - incomplete method set"); Log.d(TAG, "error: "+e, e); throw e; } - callMethod(null, mStaticContextInit, this.getApplicationContext()); + final android.view.ViewGroup viewGroup = new android.widget.FrameLayout(getApplicationContext()); + getWindow().setContentView(viewGroup); - mainClassArgs=new String[0]; // FIXME + callMethod(null, mStaticContextInit, getApplicationContext(), viewGroup); + List<String> args = data.getArguments(); + mainClassArgs=new String[args.size()]; + args.toArray(mainClassArgs); + Log.d(TAG, "onCreate - X"); } @@ -107,18 +113,26 @@ public class MainLauncher extends Activity { Log.d(TAG, "onRestart - X"); } + private volatile Thread mainThread = null; + @Override public void onResume() { Log.d(TAG, "onResume - S"); - try { - mainClazzMain.invoke(null, new Object[] { mainClassArgs } ); - } catch (InvocationTargetException ite) { - ite.getTargetException().printStackTrace(); - } catch (Throwable t) { - t.printStackTrace(); - } super.onResume(); - finish(); + if(null == mainThread) { + mainThread = new Thread("Main") { + public void run() { + try { + mainClazzMain.invoke(null, new Object[] { mainClassArgs } ); + } catch (InvocationTargetException ite) { + ite.getTargetException().printStackTrace(); + } catch (Throwable t) { + t.printStackTrace(); + } + mainThread = null; + } }; + mainThread.start(); + } Log.d(TAG, "onResume - X"); } @@ -152,6 +166,10 @@ public class MainLauncher extends Activity { @Override public void finish() { Log.d(TAG, "finish - S"); + if(null != mainThread) { + mainThread.destroy(); + mainThread = null; + } super.finish(); Log.d(TAG, "finish - X"); } diff --git a/src/java/jogamp/common/os/android/StaticContext.java b/src/java/jogamp/common/os/android/StaticContext.java index d7f134a..359e603 100644 --- a/src/java/jogamp/common/os/android/StaticContext.java +++ b/src/java/jogamp/common/os/android/StaticContext.java @@ -29,9 +29,11 @@ package jogamp.common.os.android; import android.content.Context; import android.util.Log; +import android.view.ViewGroup; public class StaticContext { private static Context appContext = null; + private static ViewGroup contentViewGroup = null; private static boolean DEBUG = false; @@ -42,19 +44,32 @@ public class StaticContext { * @throws RuntimeException if the context is already registered. */ public static final synchronized void init(Context appContext) { + init(appContext, null); + } + + /** + * Register Android application context w/ a ViewGroup for static usage. + * + * @param appContext mandatory application Context + * @param contentViewGroup optional ViewGroup acting as the Window's ContentView, usually a FrameLayout instance. + * @throws RuntimeException if the context is already registered. + */ + public static final synchronized void init(Context appContext, ViewGroup contentViewGroup) { if(null != StaticContext.appContext) { throw new RuntimeException("Context already set"); } - if(DEBUG) { Log.d(MD.TAG, "init(appCtx "+appContext+")"); } + if(DEBUG) { Log.d(MD.TAG, "init(appCtx "+appContext+", viewGroup "+contentViewGroup+")"); } StaticContext.appContext = appContext; + StaticContext.contentViewGroup = contentViewGroup; } /** - * Unregister the Android application Context + * Unregister the Android application Context and ViewGroup */ public static final synchronized void clear() { if(DEBUG) { Log.d(MD.TAG, "clear()"); } appContext = null; + contentViewGroup = null; } /** @@ -64,4 +79,12 @@ public class StaticContext { public static final synchronized Context getContext() { return appContext; } + + /** + * Return the registered Android ViewGroup acting as the Window's ContentView + * @return + */ + public static final synchronized ViewGroup getContentViewGroup() { + return contentViewGroup; + } } |