app2sd support for shared libraries
This commit is contained in:
@@ -488,7 +488,7 @@ if [ "$MultiABI" = "y" ] ; then
|
||||
else
|
||||
MultiABI="armeabi"
|
||||
fi
|
||||
LibrariesToLoad="System.loadLibrary(\\\"sdl-$LibSdlVersion\\\");"
|
||||
LibrariesToLoad="\\\"sdl-$LibSdlVersion\\\""
|
||||
StaticLibraries=`grep 'APP_AVAILABLE_STATIC_LIBS' project/jni/SettingsTemplate.mk | sed 's/.*=\(.*\)/\1/'`
|
||||
for lib in $CompiledLibraries; do
|
||||
process=true
|
||||
@@ -496,7 +496,7 @@ for lib in $CompiledLibraries; do
|
||||
if [ "$lib" = "$lib1" ]; then process=false; fi
|
||||
done
|
||||
if $process; then
|
||||
LibrariesToLoad="$LibrariesToLoad System.loadLibrary(\\\"$lib\\\");"
|
||||
LibrariesToLoad="$LibrariesToLoad, \\\"$lib\\\""
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -545,7 +545,7 @@ cat project/src/Globals.java | \
|
||||
sed "s/public static int AppTouchscreenKeyboardKeysAmountAutoFire = .*;/public static int AppTouchscreenKeyboardKeysAmountAutoFire = $AppTouchscreenKeyboardKeysAmountAutoFire;/" | \
|
||||
sed "s%public static String ReadmeText = .*%public static String ReadmeText = \"$ReadmeText\".replace(\"^\",\"\\\n\");%" | \
|
||||
sed "s%public static String CommandLine = .*%public static String CommandLine = \"$AppCmdline\";%" | \
|
||||
sed "s/public LoadLibrary() .*/public LoadLibrary() { $LibrariesToLoad };/" > \
|
||||
sed "s/public static String AppLibraries.*/public static String AppLibraries[] = { $LibrariesToLoad };/" > \
|
||||
project/src/Globals.java.1
|
||||
mv -f project/src/Globals.java.1 project/src/Globals.java
|
||||
|
||||
|
||||
35
app2sd.sh
Executable file
35
app2sd.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
APK=$1
|
||||
if [ -z "$APK" ] ; then
|
||||
APK=project/bin/DemoActivity-debug.apk
|
||||
fi
|
||||
|
||||
echo Moving shared libraries on $APK to SD card
|
||||
APK=`pwd`/$APK
|
||||
|
||||
[ -e $APK ] || { echo File $APK does not exist; exit 1; }
|
||||
|
||||
TMPDIR=app2sd-$$
|
||||
|
||||
mkdir -p $TMPDIR
|
||||
cd $TMPDIR
|
||||
|
||||
unzip $APK "lib/armeabi/*" || { echo "This apk file has already been app2sd-ed, or improperly compiled"; exit 1; }
|
||||
|
||||
zip -j bindata.zip lib/armeabi/*
|
||||
mkdir assets
|
||||
split -b 1048576 -d -a 1 bindata.zip assets/bindata
|
||||
rm bindata.zip
|
||||
|
||||
zip -d $APK "lib/armeabi/*" "META-INF/*"
|
||||
|
||||
zip -0 $APK assets/bindata*
|
||||
|
||||
jarsigner -verbose -keystore ~/.android/debug.keystore -storepass "android" $APK androiddebugkey
|
||||
|
||||
zipalign 4 $APK $APK-tmp
|
||||
mv -f $APK-tmp $APK
|
||||
|
||||
cd ..
|
||||
rm -rf $TMPDIR
|
||||
@@ -9,6 +9,8 @@ import android.view.KeyEvent;
|
||||
class Globals {
|
||||
public static String ApplicationName = "CommanderGenius";
|
||||
|
||||
public static String AppLibraries[] = { "sdl-1.2", };
|
||||
|
||||
public static final boolean Using_SDL_1_3 = false;
|
||||
|
||||
// Should be zip file
|
||||
@@ -105,7 +107,3 @@ class Globals {
|
||||
public static boolean SmoothVideo = false;
|
||||
public static boolean MultiThreadedVideo = SwVideoMode;
|
||||
}
|
||||
|
||||
class LoadLibrary {
|
||||
public LoadLibrary() { System.loadLibrary("sdl-1.2"); };
|
||||
}
|
||||
|
||||
@@ -24,6 +24,16 @@ import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.view.View.OnKeyListener;
|
||||
import java.util.LinkedList;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.File;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
@@ -81,7 +91,7 @@ public class MainActivity extends Activity {
|
||||
if(mAudioThread == null) // Starting from background (should not happen)
|
||||
{
|
||||
System.out.println("libSDL: Loading libraries");
|
||||
mLoadLibraryStub = new LoadLibrary();
|
||||
LoadLibraries();
|
||||
mAudioThread = new AudioThread(this);
|
||||
System.out.println("libSDL: Loading settings");
|
||||
Settings.Load(this);
|
||||
@@ -223,19 +233,13 @@ public class MainActivity extends Activity {
|
||||
{
|
||||
if(_screenKeyboard == null)
|
||||
return;
|
||||
String text = _screenKeyboard.getText().toString();
|
||||
if( mGLView != null )
|
||||
|
||||
synchronized(textInput)
|
||||
{
|
||||
synchronized(textInput) {
|
||||
for(int i = 0; i < text.length(); i++)
|
||||
{
|
||||
DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) );
|
||||
//textInput.addLast((int)text.charAt(i));
|
||||
//textInput.addLast((int)text.codePointAt(i));
|
||||
}
|
||||
DemoRenderer.nativeTextInput( 13, 13 ); // send return
|
||||
//textInput.addLast(13);
|
||||
//textInput.addLast(13);
|
||||
String text = _screenKeyboard.getText().toString();
|
||||
for(int i = 0; i < text.length(); i++)
|
||||
{
|
||||
DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) );
|
||||
}
|
||||
}
|
||||
_videoLayout.removeView(_screenKeyboard);
|
||||
@@ -255,12 +259,19 @@ public class MainActivity extends Activity {
|
||||
myKeyListener(MainActivity parent) { _parent = parent; };
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event)
|
||||
{
|
||||
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER))
|
||||
if ((event.getAction() == KeyEvent.ACTION_UP) && ((keyCode == KeyEvent.KEYCODE_ENTER) || (keyCode == KeyEvent.KEYCODE_BACK)))
|
||||
{
|
||||
_parent.hideScreenKeyboard();
|
||||
if(keyCode == KeyEvent.KEYCODE_ENTER)
|
||||
{
|
||||
synchronized(textInput)
|
||||
{
|
||||
DemoRenderer.nativeTextInput( 13, 13 ); // send return
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR))
|
||||
if ((event.getAction() == KeyEvent.ACTION_UP) && (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR))
|
||||
{
|
||||
synchronized(textInput) {
|
||||
DemoRenderer.nativeTextInput( 8, 8 );
|
||||
@@ -376,13 +387,104 @@ public class MainActivity extends Activity {
|
||||
NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationManager.cancel(NOTIFY_ID);
|
||||
}
|
||||
|
||||
public void LoadLibraries()
|
||||
{
|
||||
try
|
||||
{
|
||||
for(String l : Globals.AppLibraries)
|
||||
{
|
||||
System.loadLibrary(l);
|
||||
}
|
||||
}
|
||||
catch ( UnsatisfiedLinkError e )
|
||||
{
|
||||
try {
|
||||
System.out.println("libSDL: Extracting APP2SD-ed libs");
|
||||
|
||||
InputStream in = null;
|
||||
try
|
||||
{
|
||||
for( int i = 0; ; i++ )
|
||||
{
|
||||
InputStream in2 = getAssets().open("bindata" + String.valueOf(i));
|
||||
if( in == null )
|
||||
in = in2;
|
||||
else
|
||||
in = new SequenceInputStream( in, in2 );
|
||||
}
|
||||
}
|
||||
catch( IOException ee ) { }
|
||||
|
||||
if( in == null )
|
||||
throw new RuntimeException("libSDL: Extracting APP2SD-ed libs failed, the .apk file packaged incorrectly");
|
||||
|
||||
ZipInputStream zip = new ZipInputStream(in);
|
||||
|
||||
File cacheDir = getCacheDir();
|
||||
try {
|
||||
cacheDir.mkdirs();
|
||||
} catch( SecurityException ee ) { };
|
||||
|
||||
byte[] buf = new byte[16384];
|
||||
while(true)
|
||||
{
|
||||
ZipEntry entry = null;
|
||||
entry = zip.getNextEntry();
|
||||
/*
|
||||
if( entry != null )
|
||||
System.out.println("Extracting lib " + entry.getName());
|
||||
*/
|
||||
if( entry == null )
|
||||
{
|
||||
System.out.println("Extracting libs finished");
|
||||
break;
|
||||
}
|
||||
if( entry.isDirectory() )
|
||||
{
|
||||
System.out.println("Warning '" + entry.getName() + "' is a directory");
|
||||
continue;
|
||||
}
|
||||
|
||||
OutputStream out = null;
|
||||
String path = cacheDir.getAbsolutePath() + "/" + entry.getName();
|
||||
|
||||
System.out.println("Saving to file '" + path + "'");
|
||||
|
||||
out = new FileOutputStream( path );
|
||||
int len = zip.read(buf);
|
||||
while (len >= 0)
|
||||
{
|
||||
if(len > 0)
|
||||
out.write(buf, 0, len);
|
||||
len = zip.read(buf);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
for(String l : Globals.AppLibraries)
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(cacheDir, libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getPath());
|
||||
System.load(libpath.getPath());
|
||||
libpath.delete();
|
||||
}
|
||||
}
|
||||
catch ( Exception ee )
|
||||
{
|
||||
System.out.println("libSDL: Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public FrameLayout getVideoLayout() { return _videoLayout; }
|
||||
|
||||
static int NOTIFY_ID = 12367098; // Random ID
|
||||
|
||||
private static DemoGLSurfaceView mGLView = null;
|
||||
private static LoadLibrary mLoadLibraryStub = null;
|
||||
private static AudioThread mAudioThread = null;
|
||||
private static DataDownloader downloader = null;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.os.Environment;
|
||||
import java.io.File;
|
||||
|
||||
import android.widget.TextView;
|
||||
import java.lang.Thread;
|
||||
@@ -205,8 +206,27 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer {
|
||||
// Thread.currentThread().setPriority((Thread.currentThread().getPriority() + Thread.MIN_PRIORITY)/2);
|
||||
|
||||
mGlContextLost = false;
|
||||
System.loadLibrary("application");
|
||||
System.loadLibrary("sdl_main");
|
||||
|
||||
String libs[] = { "application", "sdl_main" };
|
||||
try
|
||||
{
|
||||
for(String l : libs)
|
||||
{
|
||||
System.loadLibrary(l);
|
||||
}
|
||||
}
|
||||
catch ( UnsatisfiedLinkError e )
|
||||
{
|
||||
for(String l : libs)
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(context.getCacheDir(), libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getPath());
|
||||
System.load(libpath.getPath());
|
||||
libpath.delete();
|
||||
}
|
||||
}
|
||||
|
||||
Settings.Apply(context);
|
||||
accelerometer = new AccelerometerReader(context);
|
||||
// Tweak video thread priority, if user selected big audio buffer
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=16
|
||||
AppSettingVersion=17
|
||||
LibSdlVersion=1.2
|
||||
AppName="Free Heroes 2"
|
||||
AppFullName=net.sourceforge.fheroes2
|
||||
ScreenOrientation=h
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="Game data|data8.zip^Heroes 2 DEMO data files (45 Mb)|http://downloads.pcworld.com/pub/new/fun_and_games/adventure_strategy/h2demo.zip|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/h2demo.zip/download^MIDI music support (18 Mb)|http://sourceforge.net/projects/libsdl-android/files/timidity.zip/download^Essential map pack (9 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/EssentialMapPack.zip/download^Additional map pack (95 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/AdditionalMapPack.zip/download^Mega map pack (280 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/MegaMapPack.zip/download^Russian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-ru.cfg/download^Czech translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-cs.cfg/download^Spanish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-es.cfg/download^French translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-fr.cfg/download^Hungarian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-hu.cfg/download^Polish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pl.cfg/download^Portugese translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pt.cfg/download^Swedish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-sv.cfg/download"
|
||||
AppDataDownloadUrl="Game data|data9.zip^Heroes 2 DEMO data files (45 Mb)|http://downloads.pcworld.com/pub/new/fun_and_games/adventure_strategy/h2demo.zip|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/h2demo.zip/download^MIDI music support (18 Mb)|http://sourceforge.net/projects/libsdl-android/files/timidity.zip/download^Essential map pack (9 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/EssentialMapPack.zip/download^Additional map pack (95 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/AdditionalMapPack.zip/download^Mega map pack (280 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/MegaMapPack.zip/download^Russian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-ru.cfg/download^Czech translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-cs.cfg/download^Spanish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-es.cfg/download^French translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-fr.cfg/download^Hungarian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-hu.cfg/download^Polish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pl.cfg/download^Portugese translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pt.cfg/download^Swedish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-sv.cfg/download"
|
||||
SdlVideoResize=y
|
||||
SdlVideoResizeKeepAspect=n
|
||||
NeedDepthBuffer=n
|
||||
SwVideoMode=y
|
||||
AppUsesMouse=y
|
||||
AppNeedsTwoButtonMouse=y
|
||||
AppNeedsArrowKeys=n
|
||||
@@ -22,8 +23,8 @@ AppTouchscreenKeyboardKeysAmount=0
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
RedefinedKeysScreenKb="LCTRL M T H E C SPACE C S L"
|
||||
MultiABI=n
|
||||
AppVersionCode=225912
|
||||
AppVersionName="2259.12"
|
||||
AppVersionCode=226512
|
||||
AppVersionName="2265.12"
|
||||
CompiledLibraries="sdl_net sdl_mixer sdl_image sdl_ttf png intl"
|
||||
CustomBuildScript=n
|
||||
AppCflags='-finline-functions -O2 -DWITH_ZLIB -DWITH_MIXER -DWITH_XML -DWITH_IMAGE -DWITH_TTF -DWITH_AI=simple'
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
ballfield
|
||||
fheroes2
|
||||
@@ -33,6 +33,7 @@ static char ** argv = NULL;
|
||||
static int threadedMain(void * unused)
|
||||
{
|
||||
SDL_main( argc, argv );
|
||||
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Application closed, calling exit(0)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
10
readme.txt
10
readme.txt
@@ -167,6 +167,16 @@ memcpy( &i, p, sizeof(int) ); // The correct way to dereference a non-aligned po
|
||||
This compiler flags will catch most obvious errors, you may add them to AppCflags var in settings:
|
||||
-Werror=strict-aliasing -Werror=cast-align -Werror=pointer-arith -Werror=address
|
||||
|
||||
The application will automatically get moved to SD-card on Android 2.2 or newer,
|
||||
(or you can install app2sd for older, but rooted phones),
|
||||
however the shared libraries have to be stored on the device internal storage,
|
||||
and that may be not desired for older phones with very little storage.
|
||||
The script app2sd.sh will re-package your .apk file in such a way that
|
||||
the shared libraries will not be extracted by Android OS but by application itself,
|
||||
and it will remove them from internal storage right after starting up,
|
||||
so you still need that space free, but only temporarily.
|
||||
|
||||
|
||||
How to compile your own application using automake/configure scripts
|
||||
====================================================================
|
||||
|
||||
|
||||
Reference in New Issue
Block a user