diff --git a/Source/Android/AndroidManifest.xml b/Source/Android/AndroidManifest.xml
index 5525ddc02f..12fa07c71b 100644
--- a/Source/Android/AndroidManifest.xml
+++ b/Source/Android/AndroidManifest.xml
@@ -21,14 +21,13 @@
android:label="@string/app_name"
android:allowBackup="true">
+ android:theme="@android:style/Theme.Holo.Light" >
+
+
-
@@ -37,10 +36,6 @@
android:name="org.dolphinemu.dolphinemu.about.AboutActivity"
android:theme="@android:style/Theme.Holo.Light" />
-
-
@@ -55,6 +50,8 @@
android:label="@string/settings"
android:theme="@android:style/Theme.Holo.Light" />
+
+
diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/AssetCopyService.java b/Source/Android/src/org/dolphinemu/dolphinemu/AssetCopyService.java
new file mode 100644
index 0000000000..779feee707
--- /dev/null
+++ b/Source/Android/src/org/dolphinemu/dolphinemu/AssetCopyService.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2014 Dolphin Emulator Project
+ * Licensed under GPLv2
+ * Refer to the license.txt file included.
+ */
+
+package org.dolphinemu.dolphinemu;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.os.Environment;
+import android.util.Log;
+
+import org.dolphinemu.dolphinemu.settings.UserPreferences;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * A service that spawns its own thread in order to copy several binary and shader files
+ * from the Dolphin APK to the external file system.
+ */
+public final class AssetCopyService extends IntentService
+{
+ private static final String TAG = "DolphinEmulator";
+
+ public AssetCopyService()
+ {
+ // Superclass constructor is called to name the thread on which this service executes.
+ super("AssetCopyService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent)
+ {
+ String BaseDir = Environment.getExternalStorageDirectory() + File.separator + "dolphin-emu";
+ String ConfigDir = BaseDir + File.separator + "Config";
+ String GCDir = BaseDir + File.separator + "GC";
+
+ // Copy assets if needed
+ File file = new File(GCDir + File.separator + "font_sjis.bin");
+ if(!file.exists())
+ {
+ NativeLibrary.CreateUserFolders();
+ copyAsset("Dolphin.ini", ConfigDir + File.separator + "Dolphin.ini");
+ copyAsset("dsp_coef.bin", GCDir + File.separator + "dsp_coef.bin");
+ copyAsset("dsp_rom.bin", GCDir + File.separator + "dsp_rom.bin");
+ copyAsset("font_ansi.bin", GCDir + File.separator + "font_ansi.bin");
+ copyAsset("font_sjis.bin", GCDir + File.separator + "font_sjis.bin");
+ copyAssetFolder("Shaders", BaseDir + File.separator + "Shaders");
+ }
+ else
+ {
+ Log.v(TAG, "Skipping asset copy operation.");
+ }
+
+ // Always copy over the GCPad config in case of change or corruption.
+ // Not a user configurable file.
+ copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
+
+ // Load the configuration keys set in the Dolphin ini and gfx ini files
+ // into the application's shared preferences.
+ UserPreferences.LoadIniToPrefs(this);
+ }
+
+ private void copyAsset(String asset, String output)
+ {
+ Log.v(TAG, "Copying " + asset + " to " + output);
+ InputStream in = null;
+ OutputStream out = null;
+
+ try
+ {
+ in = getAssets().open(asset);
+ out = new FileOutputStream(output);
+ copyFile(in, out);
+ in.close();
+ out.close();
+ }
+ catch (IOException e)
+ {
+ Log.e(TAG, "Failed to copy asset file: " + asset, e);
+ }
+ }
+
+ private void copyAssetFolder(String assetFolder, String outputFolder)
+ {
+ Log.v(TAG, "Copying " + assetFolder + " to " + outputFolder);
+
+ try
+ {
+ for (String file : getAssets().list(assetFolder))
+ {
+ copyAsset(assetFolder + File.separator + file, outputFolder + File.separator + file);
+ }
+ }
+ catch (IOException e)
+ {
+ Log.e(TAG, "Failed to copy asset folder: " + assetFolder, e);
+ }
+ }
+
+ private void copyFile(InputStream in, OutputStream out) throws IOException
+ {
+ byte[] buffer = new byte[1024];
+ int read;
+
+ while ((read = in.read(buffer)) != -1)
+ {
+ out.write(buffer, 0, read);
+ }
+ }
+}
diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java
deleted file mode 100644
index 62f64f0ea2..0000000000
--- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Copyright 2013 Dolphin Emulator Project
- * Licensed under GPLv2
- * Refer to the license.txt file included.
- */
-
-package org.dolphinemu.dolphinemu;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
-import org.dolphinemu.dolphinemu.settings.UserPreferences;
-
-import java.io.*;
-
-/**
- * The main activity of this emulator front-end.
- */
-public final class DolphinEmulator extends Activity
-{
- private void CopyAsset(String asset, String output)
- {
- InputStream in = null;
- OutputStream out = null;
-
- try
- {
- in = getAssets().open(asset);
- out = new FileOutputStream(output);
- copyFile(in, out);
- in.close();
- out.close();
- }
- catch (IOException e)
- {
- Log.e("DolphinEmulator", "Failed to copy asset file: " + asset, e);
- }
- }
-
- private void CopyAssetFolder(String assetFolder, String outputFolder)
- {
- try
- {
- for (String file : getAssets().list(assetFolder))
- {
- CopyAsset(assetFolder + File.separator + file, outputFolder + File.separator + file);
- }
- }
- catch (IOException e)
- {
- Log.e("DolphinEmulator", "Failed to copy asset folder: " + assetFolder, e);
- }
- }
-
- private void copyFile(InputStream in, OutputStream out) throws IOException
- {
- byte[] buffer = new byte[1024];
- int read;
-
- while ((read = in.read(buffer)) != -1)
- {
- out.write(buffer, 0, read);
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- if (savedInstanceState == null)
- {
- Intent GameListIntent = new Intent(this, GameListActivity.class);
- startActivity(GameListIntent);
-
- String BaseDir = Environment.getExternalStorageDirectory()+File.separator+"dolphin-emu";
- String ConfigDir = BaseDir + File.separator + "Config";
- String GCDir = BaseDir + File.separator + "GC";
-
- // Copy assets if needed
- File file = new File(GCDir + File.separator + "font_sjis.bin");
- if(!file.exists())
- {
- NativeLibrary.CreateUserFolders();
- CopyAsset("Dolphin.ini", ConfigDir + File.separator + "Dolphin.ini");
- CopyAsset("dsp_coef.bin", GCDir + File.separator + "dsp_coef.bin");
- CopyAsset("dsp_rom.bin", GCDir + File.separator + "dsp_rom.bin");
- CopyAsset("font_ansi.bin", GCDir + File.separator + "font_ansi.bin");
- CopyAsset("font_sjis.bin", GCDir + File.separator + "font_sjis.bin");
- CopyAssetFolder("Shaders", BaseDir + File.separator + "Shaders");
- }
-
- // Always copy over the GCPad config in case of change or corruption.
- // Not a user configurable file.
- CopyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
-
- // Load the configuration keys set in the Dolphin ini and gfx ini files
- // into the application's shared preferences.
- UserPreferences.LoadIniToPrefs(this);
- }
- }
-
- @Override
- protected void onRestart()
- {
- super.onRestart();
- finish(); // If we are ever returning to this activity then we are exiting.
- }
-}
diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java
index 80bb29eb9e..96020ff0e6 100644
--- a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java
+++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java
@@ -24,6 +24,7 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
+import org.dolphinemu.dolphinemu.AssetCopyService;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.about.AboutActivity;
@@ -103,10 +104,15 @@ public final class GameListActivity extends Activity
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
- // Display the game list fragment on activity creation,
- // but only if no previous states have been saved.
+
+ // Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
if (savedInstanceState == null)
{
+ // Copy assets into appropriate locations.
+ Intent copyAssets = new Intent(this, AssetCopyService.class);
+ startService(copyAssets);
+
+ // Display the game list fragment.
final GameListFragment gameList = new GameListFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, gameList);