Custom Drawn Interface/Android
Contents
1 Architecture 2 Roadmap 3 Using the Android SDK, Emulator and Phones 4 Android Programming 5 Configuring the Free Pascal Compiler for Android o 5.1 Use the ready Virtual Box Image with FPC and Lazarus o 5.2 Building the compiler yourself in Windows o 5.3 Using the pre-compiled compiler in Windows o 5.4 Building the compiler yourself in Linux o 5.5 Using the pre-compiled compiler in Linux 6 Install the Java JDK and the Android SDK and NDK 7 Compiling the example LCL Android Application 8 How to create an LCL Android Application o 8.1 Step 1 - Creating the LPI o 8.2 Step 2 - Building the library o 8.3 Step 3 - Create the Android project structure o 8.4 Step 4 - Creating the APK package . 8.4.1 Step 4 - Creating the APK package in Linux . 8.4.2 Step 4 - Creating the APK package in Windows o 8.5 Building an LCL Android application with debug info 9 Oh no! My LCL Android application doesn't work o 9.1 The Pascal executable was compiled for a wrong architecture, operating system and/or widgetset o 9.2 My Pascal application crashed. How to get a stacktrace? o 9.3 The indispensable build options o 9.4 Wrong package name 10 Free Pascal Bugs on Android Support o 10.1 FPC4Android Branches . 10.1.1 FPC4Android 2.5.1 . 10.1.2 FPC4Android 2.6.1 11 Android SDK and NDK bugs o 11.1 Android NDK for Windows broken linker o 11.2 Error while calling DX: Trouble processing: bad class file magic (cafebabe) 12 Development Notes o 12.1 The mysterious JNI Crash o 12.2 NDK Libraries available in Android 2.2 (API level 8) o 12.3 Native text drawing o 12.4 Flood of garbage collector messages when the caret is visible o 12.5 Why the caret of a TEdit keeps blinking after clicking on the form o 12.6 Android ComboBox o 12.7 Using the Native ListView Dialog o 12.8 LazDeviceAPIs Architecture
LCL-CustomDrawn-Android utilizes a minimal Java application which communicates with our Pascal library and sends all events to it and also obeys commands from it. The communication is done via JNI as supported by Google. The controls are not native, instead they are all drawing using TRawImage+TLazIntfImage+TLazCanvas and events and the painting are clipped using LazRegions. The drawing itself is done in Pascal using jnigraphics to draw on a Bitmap Java object which is then drawn by the minimal Java activity on a SurfaceView.
Our previous and short-lived attempt to write an LCL Interface for Android (LCL-Android) utilized a non-standard method of using native executables which communicated with a Java machine via Pipes. This method was abandoned because it was considered unsupported by Google. It is considered obsolete and people should use LCL-CustomDrawn-Android instead. This older interface was documented in Android Interface. Roadmap
Part 1, until March 2012:
1. Build the set of Lazarus Custom Drawn Controls 2. Initial bindings for the Android APIs 3. Create an application to automatically generate the bindings 4. Start the new widgetset 5. Implement support for JNI 6. Merge the Lazarus Custom Drawn Controls into the LCL and use them to implement all basic controls 7. Add text support for Android 8. Implement basic window client area scrolling 9. Add mobile emulator for desktop platforms 10. Improve the mobile scrolling 11. Add text support in X11 12. Add DPI awareness and adaptation in the LCL 13. Add non-native text support via pasfreetype
Part 2: April, May, June 2012:
1. TButton improve the Android visual 2. TBitBtn 3. TRadioButton finish the native look 4. Calendar dialog -> Problematic as the LCL has no calendar dialog, it just opens a normal form and puts a calendar on it, so we need a TCDCalendar widget 5. MaskEdit 6. Improve TComboBox 7. TMemo 8. TListView as a list with columns 9. TMainMenu 10. Database with sqlite 11. Barcode reading 12. Windows add-on installer 13. Using the Android SDK, Emulator and Phones
Custom Drawn Interface/Using the Android SDK, Emulator and Phones Android Programming Configuring the Free Pascal Compiler for Android
NOTE: The cross-compiler instructions below are probably obsolete, since support for the Android target is present in the trunk (development) version 2.7.1 of FPC. Here are up to date instructions: building a cross-compiler for Android target.
Use the ready Virtual Box Image with FPC and Lazarus
The fastest way to configure Free Pascal and Lazarus for Android development is simply using a pre- configured virtual machine image which already includes Mageia Linux 1, KDE, Lazarus 0.9.31, Subversion, Free Pascal for both x86-linux and arm-linux (targetting Android), the Android SDK, the Android NDK, Java, Ant, Gtk2 and all it's development packages, the GNU debugger (GDB), subversion and everything else necessary for building Android applications with Lazarus.
The download like for the virtual machine image is: https://sourceforge.net/projects/p- tools/files/Lazarus_for_Android_VM_Image/snapshot_30_dez_2011/ (warning: the VirtualBox image was created using the Mac OS X default Zip utility and not all zip applications can handle it. The Mac OS X default zip application can, and PeaZip too and WinRAR too. Both 7-Zip and the Windows 7 default unzipper fail.
The virtual machine image is composed by two files: “Android Devel VM.vbox” and “Android Devel VM.hdd”. Both need to be located in the same folder and also note that the source forge download is a zipped file, so it needs to be unzipped. After unzipping the VM image has 5,2GB. To use this virtual machine one should install Virtual Box and then use it to open the .vbox file. Then one can already use this Linux virtual machine to build Android applications. The process of building an application involves first opening Lazarus and building the application in Lazarus, for example the example project available on ~/Programas/lazarus/example/androidlcl/ and then going into the Linux terminal, navigating to ~/Programas/lazarus/example/androidlcl/android and issuing the command “ant debug” which will generate the APK file in ~/Programas/ lazarus/example/androidlcl/android/bin/LCLExample-debug.apk. There are two users in the virtual machine: “root” and “pascaldev” and both of them use the password “root”.
Note that the virtual machine contains the Lazarus source code from when it was created, but one can also use svn update to get the latest code. Note that this involves some risks, however, as the trunk version might ocasionally contain problems.
Building the compiler yourself in Windows
Step 1 - Install the Android SDK and NDK
Download from Google and install both the SDK and the NDK for Windows. Check your path to the binutils installed by the NDK. For example, for NDK r7 installed in C:\Programas\android-ndk-r7\ the path is C:\Programas\android-ndk-r7\toolchains\arm-linux- androideabi-4.4.3\prebuilt\windows\bin
Also check your path to the libraries installed by the NDK. For example, for NDK r7 installed in C:\Programas\android-ndk-r7\ the path is C:\Programas\android-ndk-r7\platforms\android-8\arch- arm\usr
Step 2 - Download FPC 2.5.1 from January 19th
Create a folder to store the FPC trunk source code and checkout revision 16790
Or if you want support for database and many other nice fixes use the branch fpc4android from here: svn co https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android fpc4android
Step 3 - Install FPC 2.4.4
An easy way to obtain a good FPC 2.4.4 is installing Lazarus 0.9.30.2. For example, let's say you install this Lazarus version in C:\Programas\lazarusfpc244
Step 4 - Create the build script and built it
Create the output directory, for example: C:\Programas\fpcandroid\output
Next create a file called build.bat in the fpc root folder, in our example C:\Programas\fpcandroid and copy to it:
SET PATH=C:\Programas\lazarusfpc244\fpc\2.4.4\bin\i386-win32\ make crossinstall CPU_TARGET=arm OS_TARGET=linux CROSSBINDIR=C:\Programas\android- ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin OPT=-dFPC_ARMEL BINUTILSPREFIX=arm-linux-androideabi- INSTALL_PREFIX=C:\Programas\fpcandroid\output pause
Next run this batch script and you should have FPC installed into C:\Programas\fpcandroid\output
Step 5 - Copy some cross-binutils into the bin dir
You now should have a FPC binary in C:\Programas\fpcandroid\output\bin\i386-win32
Now get these 3 files:
C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux- androideabi-as.exe C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi- 4.4.3\prebuilt\windows\bin\arm-linux-androideabi-ld.exe C:\Programas\android-ndk-r7\toolchains\arm- linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux-androideabi-strip.exe
And copy and then rename to have:
C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-as.exe C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-ld.exe C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-strip.exe Step 6 - Merge this into a Lazarus FPC setup
Let's say you have the following Lazarus C:\Programas\lazarus31 with the following fpc installed inside it: C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 and C:\Programas\lazarus31\fpc\2.6.1\units\
Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linux and copy C:\Programas\fpcandroid\output\units\arm-linux there
Copy all .exe files from C:\Programas\fpcandroid\output\bin\i386-win32\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32
(! copy the exe-files to FPC 2.6.1 !)
Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode
Using the pre-compiled compiler in Windows
Step 1 - Download and unzip the pre-compiled compiler
The download is available here: https://sourceforge.net/projects/p- tools/files/Free%20Pascal%20for%20ARM/Windows/
Step 2 - Merge it into the FPC installation
Let's say you have the following Lazarus C:\Programas\lazarus31 with the following fpc installed inside it: C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 and C:\Programas\lazarus31\fpc\2.6.1\units\
Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linx and copy fpc4android_2_5_1_26_mar_2012\units\arm-linux there
Copy all .exe files from fpc4android_2_5_1_26_mar_2012\bin\i386-win32\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 (the version here should be of the installed Windows compiler, not the version of the cross-compiler, so might be 2.6.0 or 2.7.1 or something else)
Step 3 - Install the Java JDK and the Android SDK and NDK
If you haven't done so already, then install the Java JDK and the Android SDK and NDK. I recommend the JDK 6 (JDK 7 doesnt work!), latest SDK and the NDK version 7. The Windows NDK 7b has a serious bug: [1] Some people also report that 7c works fine, and I tested that 8c works fine.
Java JDK (!WARNING! Download JDK version 6! Version 7 does not work!!!): http://www.oracle.com/technetwork/java/javase/downloads/index.html Android SDK Download (!WARNING! Instead of clicking in the first download link that you see, go to "Use an existing IDE"!): http://developer.android.com/sdk/index.html !WARNING! The SDKs r21 and superior removed the nice apkbuilder.bat script which is utilized in our build system in Windows. If you want to use our Windows build scripts, download the SDK r20 from this link: http://dl.google.com/android/installer_r20-windows.exe Android NDK version 7 download link: http://dl.google.com/android/ndk/android-ndk-r7- windows.zip Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode and these instructions: Custom Drawn Interface/Android#Compiling_the_example_LCL_Android_Application
Building the compiler yourself in Linux
See Setup_Cross_Compile_For_ARM and make sure to use the option OPT="-dFPC_ARMEL" for building the compiler.
Using the pre-compiled compiler in Linux
A pre-compiled compiler is provided for convenience for users. The following steps were tested in Mandriva Linux 2010.0 and 2010.1:
Required Environment
The latest stable FPC installed in the system via the RPM / DEB / TAR package
Step 1 - Install the cross-binutils
For Mandriva Linux the RPM package containing arm-linux-as, arm-linux-ld, etc, which are the cross- binutils can be found here: http://rpm.pbone.net/index.php3/stat/4/idpl/14252825/dir/mandriva_2010/com/cross-arm-binutils- 2.20.51.0.4-2mnb2.i586.rpm.html
Just download the RPM package and install it using: rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
In Mandriva Linux 2010.0 the dependencies won't match, as the package is for 2010.1, but one can simply ignore this problem and it works fine using --nodeps: rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
For other distributions use the corresponding package, or else read the instructions for building the cross-binutils yourself at Setup_Cross_Compile_For_ARM
Step 2 - Configure the cross-binutils
The assembler needs a parameter to tell it which ARM ABI to use. A choice which works good is EABI-5, which is compatible with all Android devices available as of Jan 2011. To set this, we will rename the original assembler and substitute it with a shell script which passes the desired parameter. These commands will do it: su mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org gedit /usr/bin/arm-linux-as
Now paste into the editor this code: #!/bin/sh /usr/bin/arm-linux-as_org -meabi=5 $@
And don't forget to then make it executable: chmod 755 /usr/bin/arm-linux-as
Step 3 - Install the Free Pascal Cross-Compiler
At this point the pre-compiled FPC can be download from here: http://sourceforge.net/projects/p- tools/files/Free%20Pascal%20for%20ARM/
Then use these commands to install the pre-compiled Free Pascal cross-compiler into /usr:
[felipe@localhost Programas]$ ls -l total 20664 -rw-rw-r-- 1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz [felipe@localhost Programas]$ su Password: [root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/ [root@localhost Programas]# cd /usr/ [root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz [root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm
Step 4 - Verify if your Cross-Compiler works
If you made no errors in the previous steps, it should work, so try to call it like this:
[felipe@localhost Programas]$ /usr/bin/ppcrossarm
If this command works and fpc shows its options, then you configured the cross-compiler correctly, if not, then try to find out if your symbolic link points to a correct location with this command:
[felipe@localhost Programas]$ ls -ls /usr/bin/ppc*
Now we are ready to compile Android applications using the Lazarus IDE! Configuring the fpc.cfg file isn't necessary, the old compiler will automatically find the new compiler and it's object files. Install the Java JDK and the Android SDK and NDK
If you haven't done so already, then install the Java JDK and the Android SDK and NDK. I recommend the JDK 6 (JDK 7 doesnt work!), latest SDK and the NDK version 7. The Windows NDK 7b has a serious bug: [2] Some people also report that 7c works fine, and I tested that 8c works fine.
Java JDK (Choose version 6!): http://www.oracle.com/technetwork/java/javase/downloads/index.html Android SDK Download (Choose Use an existing IDE!): http://developer.android.com/sdk/index.html Android NDK version 7 download link: http://dl.google.com/android/ndk/android-ndk-r7- windows.zip
Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode and these instructions: Custom Drawn Interface/Android#Compiling_the_example_LCL_Android_Application Compiling the example LCL Android Application
Step 1 - Download the source code
The source code of the example is located inside the Lazarus sources in lazarus/examples/androidlcl/androidlcltest.lpi
Step 2 - Make sure you have the Java JDK and the Android SDK and NDK installed
Read here: Custom_Drawn_Interface/Android#Install_the_Java_JDK_and_the_Android_SDK_and_NDK
Step 3 - Build the project using the Lazarus IDE
Configuring Lazarus itself to use the new compiler should not normally be necessary because fpc should be able to find the symlink created, but if you have trouble in this part you can try to hard code the compiler path to use the new crosscompiler. To hardcode the compiler path in cause of trouble go to the menu "Tools->Options" and change the "Compiler Path" to "/usr/bin/ppcrossarm"
But it is necessary to configure the LPI file to build the example. Open the Project Options dialog of the androidlcltest.lpi project and go to the section Paths and change the libraries path to reflect the correct paths of where your Android NDK was installed and where your jnigraphics.so, libc.so, etc, libraries are located for your target Android API level. For LCL-CustomDrawn-Android API level 8 is the best choice, because it supports Android 2.2+ like the LCL. The image bellow shows where to configure this: The actual lazarus release contains a error, they create a .so.so - file instead of a .so - file. So you have to change this manually in lazarus.
Step 4 - Build the APK
If you are using Windows, use these instructions to build the APK: Custom Drawn Interface/Android#Step_4_-_Creating_the_APK_package_in_Windows
If you are using Linux follow these instructions instead: Before going to the command line to build the APK open the file lazarus/examples/androidlcl/android/local.properties and change it to reflect your Android SDK path. The file says you should not modify it, but ignore that and modify it anyway. Here is how the file looks like:
# This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must *NOT* be checked in Version Control Systems, # as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant # For customization when using a Version Control System, please read the # header note. sdk.dir=/home/felipe/Programas/android-sdk-linux
After configuring that one, go to the command line and issue these commands:
cd lazarus/examples/androidlcl/android ant debug
The APK will be located in lazarus/examples/androidlcl/android/bin
Step 5 - Install the APK in your phone and run it
You can install via ADB or by copying the file to the sdcard. You should see this: How to create an LCL Android Application
To create a new LCL-CustomDrawn-Android application simply copy all of the file structure and build and java files from the example project called "androidlcl". This example can be obtained from the Lazarus source tree in lazarus/examples/androidlcl
Then you will need to modify the build files to change them to your new project name and your new Java package name.
Step 1 - Creating the LPI
You need a separate LPI at the moment for the Android version of the application but all the rest of the code can be shared. Create it using the template for a "Library" and then adapt the code from the example located in the lazarus source code in lazarus/examples/androidlcl
You need to adapt the exported JNI method names to your Android Package Name.
Step 2 - Building the library
First of all, build the Pascal executable without debug information. This debug information is not so useful in Android and makes the executable much bigger. Open the menu Project->Project Options and set the build mode, widgetset, architecture and operating system targets, as shown in these screenshots: