Hello Tomas,

I attached the patch for the FXActivity and DalvikLauncher classes. To make this work, you need to patch the build process for the created projects as well. I couldn't find where this is done in the repo, so I did this manually every time :-), this is also the reason why it isn't included in the patch file. This is not optimized so there is still a hardcoded reference to the application jar in here, perhaps you can generalize this:

custom_rules.xml:
target init-env:
      add  <property name="app.lib.dir" value="app-libs" />

target install-application:
change to
    <target name="-install-application" unless="app.uptodate">
    <mkdir dir="${app.lib.dir}"/>
        <copy todir="${app.lib.dir}">
            <fileset dir="${jfx.app.dist.dir}" includes="*.jar"/>
        </copy>
    </target>


build-extras.xml:
add
<property name="output-dex-file" value="${out.absolute.dir}/app_dex/${dex.file.name}"/>
            <mkdir dir="${out.absolute.dir}/app_dex"/>
            <exec executable="${dx}" failonerror="true">
                <arg value="--dex" />
                <arg value="-JXmx2048m" />
                <arg value="--output=${output-dex-file}" />
                <extra-parameters />
                <arg line="${verbose.option}" />
                <arg line="${nolocals.option}" />
                <arg path="${out.dex.input.absolute.dir}" />
                <arg line="${app.lib.dir}/MyApplication.jar"/>
                <external-libs />
            </exec>
            <jar destfile="${asset.absolute.dir}/Application_dex.jar"
                   basedir="${out.absolute.dir}/app_dex"
                   includes="${dex.file.name}" />

right after the first <exec executable="${dx}" .... />

I hope I didn't forget anything.

Kind regards,
Sebastian

Am 02.12.2013 10:27, schrieb tomas.brandalik:
Hi Sebastian,
please would you send the patch to me?

thank you in advance
-Tomas

On 12/02/2013 09:55 AM, Sebastian Rheinnecker wrote:
Hi again,

I just wanted to let you know that I solved the issue with the max method references in the dex files with using multiple dex files. To accomplish this I patched the classes FXActivity and DalvikLauncher to dynamically load the second dex file and its classes. I also patched the build process so that any application jar can be used for this. If anyone runs into the same issue, just contact me.

Kind regards,
Sebastian Rheinnecker

Am 26.11.2013 14:27, schrieb Sebastian Rheinnecker:
Hi,

I used your instructions with some tweaks to build a JavaFX application for android on Windows. However, it turns out that Android's dex format is putting a spoke into our wheel with the 65k method reference limit. The JavaFX runtime itself already contains 51k method references and because of that I was not yet able to bring our full application showcase to android. So if some android expert could contribute to the project by showing how to use multiple dex files, one containing the javafx runtime and one for the application, that would be great. Any help on the mailing list is appreciated as well.

Kind regards,
Sebastian Rheinnecker

Am 16.11.2013 19:53, schrieb Johan Vos:
Hi,

Since I (and others) think it is very important that we can have
JavaFX applications running on Android (and IOS, but in this mail I
limit myself to Android), I created a bitbucket project containing
code and build instructions to run JavaFX applications on Android.

I didn't do much myself. Rather, this project is about providing easy
and consistent build instructions. I combined information from this
mailinglist with information I could find online, and with help from
the JavaFX team.

The project is here: https://bitbucket.org/johanvos/jfx78

After I gathered the information, it didn't cost me much time to get
HelloWorld running on my Samsung S3 mini. I never wrote an Android
project before, and I never used the Android SDK or NDK before I
started with this thing almost a week ago. Hence, it is not that hard
to create a JavaFX application on Android.

This project is far from finished. There are a number of things that
have to be done:
* Improve build instructions
* Simplify build
* Fix bugs (e.g. touch-events are not processed yet)
* Manage the synchronization with the main JavaFX repo
* create plugins for IDE's or maven to automatically build the Android packages

I want to open this project at this early stage, though, since I think
it is important to have more community input. Also, I want to give a
shout to the world that JavaFX on Android is not a dream.

I hope many of you try out the instructions, improve them, correct
them, and test your applications on Android.

Thanks a lot to all the people on this mailinglist for telling how
they were dealing with JavaFX on Android. Again, I didn't write much
code, but rather tried to combine the information and make it useful
for everybody.

I know there is an intense debate about the role of Oracle on the
Android (and IOS) ports. Let me close with a similar situation. About
17 years ago (sigh, time flies), I was involved with the port of Java
to Linux, as part of the Blackdown team. Initially, we didn't get much
help from Sun Microsystems (it was even not easy to get the latest
code). But once we showed that we could run the thing on Linux, and
that many developers were interested in it, Sun started to add
resources on this as well. Eventually, we became obsolete. I hope to
reach the obsolete stage on this project as well.

Again, the project can be found here:https://bitbucket.org/johanvos/jfx78

- Johan







--
Sebastian Rheinnecker
phone: +49 7071 9709050
fax: +49 7071 9709051

yWorks GmbH
Vor dem Kreuzberg 28
72070 Tuebingen
Germany
http://www.yworks.com
Managing Directors: Sebastian Müller, Michael Pfahler
Commercial Registry: Stuttgart, Germany, HRB 382340

# HG changeset patch
# User Sebastian Rheinnecker <sebastian.rheinnec...@yworks.com>
# Date 1385977278 -3600
# Node ID f4fc935ac56fe0226cc169a6d8651f69ec346955
# Parent  ace86ff6a0233960d6226e2ae4762783e579403f
use separate dex files for library and application

diff -r ace86ff6a023 -r f4fc935ac56f 
modules/graphics/src/android/java/com/oracle/dalvik/DalvikLauncher.java
--- a/modules/graphics/src/android/java/com/oracle/dalvik/DalvikLauncher.java   
Wed Nov 20 19:23:14 2013 +0100
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/DalvikLauncher.java   
Mon Dec 02 10:41:18 2013 +0100
@@ -26,13 +26,18 @@
 package com.oracle.dalvik;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.util.Log;
+import dalvik.system.DexClassLoader;
+
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.util.Map.Entry;
 import java.util.Properties;
+import java.io.File;
+
 
 public class DalvikLauncher implements Launcher {
 
@@ -127,10 +132,22 @@
     private Class resolveApplicationClass()
                        throws PackageManager.NameNotFoundException, 
ClassNotFoundException {
 
-               Class clazz = null;
+      // Internal storage where the DexClassLoader writes the optimized dex 
file to.
+      final File optimizedDexOutputPath = activity.getDir("outdex", 
Context.MODE_PRIVATE);
+
+      final File dexInternalStoragePath = new File(activity.getDir("dex", 
Context.MODE_PRIVATE),
+          FXActivity.APPLICATION_DEX_NAME);
+
+      // Initialize the class loader with the secondary dex file.
+      DexClassLoader cl = new 
DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
+          optimizedDexOutputPath.getAbsolutePath(),
+          null,
+          activity.getClassLoader());
+
+      Class clazz = null;
         String applicationClassName = metadata.getString(META_DATA_MAIN_CLASS);
                if (applicationClassName != null && 
applicationClassName.length() > 0) {
-                       clazz = Class.forName(applicationClassName);
+                       clazz = cl.loadClass(applicationClassName);
                }
                return clazz;
        }
diff -r ace86ff6a023 -r f4fc935ac56f 
modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java
--- a/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java       
Wed Nov 20 19:23:14 2013 +0100
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java       
Mon Dec 02 10:41:18 2013 +0100
@@ -44,6 +44,14 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
 public class FXActivity extends Activity implements SurfaceHolder.Callback, 
         SurfaceHolder.Callback2 {
        
@@ -52,6 +60,8 @@
     private static final String GLASS_LENS_ANDROID_LIB      = 
"glass_lens_android";
     private static final String META_DATA_LAUNCHER_CLASS    = "launcher.class";
     private static final String DEFAULT_LAUNCHER_CLASS      = 
"com.oracle.dalvik.JavaSELauncher";
+    public static final String APPLICATION_DEX_NAME = "Application_dex.jar";
+    static final int BUF_SIZE = 8 * 1024;
     
     private static FXActivity   instance;
     private static Launcher     launcher;
@@ -80,7 +90,32 @@
         setContentView(mViewGroup);
         instance = this;     
         Log.v(TAG, "Loading glass native library.");
-        System.loadLibrary(GLASS_LENS_ANDROID_LIB);        
+        System.loadLibrary(GLASS_LENS_ANDROID_LIB);
+
+        // Before the secondary dex file can be processed by the 
DexClassLoader,
+        // it has to be first copied from asset resource to a storage location.
+        File dexInternalStoragePath = new File(getDir("dex", 
Context.MODE_PRIVATE),
+            APPLICATION_DEX_NAME);
+        BufferedInputStream bis;
+        OutputStream dexWriter;
+
+        try {
+          bis = new 
BufferedInputStream(getAssets().open(APPLICATION_DEX_NAME));
+          dexWriter = new BufferedOutputStream(
+              new FileOutputStream(dexInternalStoragePath));
+          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();
+
+        } catch (FileNotFoundException e) {
+          e.printStackTrace();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
     }
     
     private Bundle getMetadata() {
@@ -105,7 +140,7 @@
             launcher.launchApp(this, metaData);
             
         } catch (Exception ex) {
-            throw new RuntimeException("Did not created correct launcher.", 
ex);
+            throw new RuntimeException("Did not create correct launcher.", ex);
         }
     }
     

Reply via email to