Skip to content
Snippets Groups Projects
Commit 35149a10 authored by sapier's avatar sapier
Browse files

Speedup initial android startup on some devices by factor 10 or more

parent aaec558f
No related branches found
No related tags found
No related merge requests found
......@@ -629,6 +629,7 @@ assets : $(ASSETS_TIMESTAMP)
find . -name "timestamp" -exec rm {} \; ; \
find . -name "*.blend" -exec rm {} \; ; \
ls -R | grep ":$$" | sed -e 's/:$$//' -e 's/\.//' -e 's/^\///' > "index.txt"; \
find Minetest >"filelist.txt"; \
cp ${ROOT}/${ASSETS_TIMESTAMP} ${ROOT}/${ASSETS_TIMESTAMP}.old; \
else \
echo "nothing to be done for assets"; \
......
......@@ -8,6 +8,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Vector;
import java.util.Iterator;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
......@@ -20,10 +21,11 @@ import android.view.Display;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MinetestAssetCopy extends Activity {
public class MinetestAssetCopy extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.assetcopy);
......@@ -35,8 +37,24 @@ public class MinetestAssetCopy extends Activity {
m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8);
m_ProgressBar.invalidate();
m_AssetCopy = new copyAssetTask();
m_AssetCopy.execute();
/* check if there's already a copy in progress and reuse in case it is*/
MinetestAssetCopy prevActivity =
(MinetestAssetCopy) getLastNonConfigurationInstance();
if(prevActivity!= null) {
m_AssetCopy = prevActivity.m_AssetCopy;
}
else {
m_AssetCopy = new copyAssetTask();
m_AssetCopy.execute();
}
}
/* preserve asset copy background task to prevent restart of copying */
/* this way of doing it is not recommended for latest android version */
/* but the recommended way isn't available on android 2.x */
public Object onRetainNonConfigurationInstance()
{
return this;
}
ProgressBar m_ProgressBar;
......@@ -44,109 +62,53 @@ public class MinetestAssetCopy extends Activity {
copyAssetTask m_AssetCopy;
private class copyAssetTask extends AsyncTask<String, Integer, String>{
private void copyElement(String name, String path) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String full_path;
if (path != "") {
full_path = path + "/" + name;
}
else {
full_path = name;
}
//is a folder read asset list
if (m_foldernames.contains(full_path)) {
m_Foldername = full_path;
publishProgress(0);
File current_folder = new File(baseDir + "/" + full_path);
if (!current_folder.exists()) {
if (!current_folder.mkdirs()) {
Log.w("MinetestAssetCopy","\t failed create folder: " + baseDir + "/" + full_path);
}
else {
Log.w("MinetestAssetCopy","\t created folder: " + baseDir + "/" + full_path);
}
}
try {
String[] current_assets = getAssets().list(full_path);
for(int i=0; i < current_assets.length; i++) {
copyElement(current_assets[i],full_path);
}
} catch (IOException e) {
Log.w("MinetestAssetCopy","\t failed to read contents of folder");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//is a file just copy
else {
boolean refresh = true;
File testme = new File(baseDir + "/" + full_path);
long asset_filesize = -1;
long stored_filesize = -1;
if (testme.exists()) {
try {
AssetFileDescriptor fd = getAssets().openFd(full_path);
asset_filesize = fd.getLength();
fd.close();
} catch (IOException e) {
refresh = true;
m_asset_size_unknown.add(full_path);
}
stored_filesize = testme.length();
if (asset_filesize == stored_filesize) {
refresh = false;
}
}
if (refresh) {
m_tocopy.add(full_path);
}
}
}
private long getFullSize(String filename) {
private class copyAssetTask extends AsyncTask<String, Integer, String>
{
private long getFullSize(String filename)
{
long size = 0;
try {
InputStream src = getAssets().open(filename);
byte[] buf = new byte[1024];
int len = 0;
while ((len = src.read(buf)) > 0) {
size += len;
}
InputStream src = getAssets().open(filename);
byte[] buf = new byte[4096];
int len = 0;
while ((len = src.read(buf)) > 0)
{
size += len;
}
}
catch (IOException e) {
catch (IOException e)
{
e.printStackTrace();
}
return size;
}
@Override
protected String doInBackground(String... files) {
protected String doInBackground(String... files)
{
m_foldernames = new Vector<String>();
m_filenames = new Vector<String>();
m_tocopy = new Vector<String>();
m_asset_size_unknown = new Vector<String>();
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
String baseDir =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/";
// prepare temp folder
File TempFolder = new File(baseDir + "Minetest/tmp/");
if (!TempFolder.exists()) {
if (!TempFolder.exists())
{
TempFolder.mkdir();
}
else {
File[] todel = TempFolder.listFiles();
for(int i=0; i < todel.length; i++) {
Log.w("MinetestAssetCopy","deleting: " + todel[i].getAbsolutePath());
for(int i=0; i < todel.length; i++)
{
Log.v("MinetestAssetCopy","deleting: " + todel[i].getAbsolutePath());
todel[i].delete();
}
}
......@@ -156,52 +118,49 @@ public class MinetestAssetCopy extends Activity {
OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
dst.close();
} catch (IOException e) {
Log.w("MinetestAssetCopy","Failed to create .nomedia file");
Log.e("MinetestAssetCopy","Failed to create .nomedia file");
e.printStackTrace();
}
try {
InputStream is = getAssets().open("index.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while(line != null){
m_foldernames.add(line);
line = reader.readLine();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
copyElement("Minetest","");
// build lists from prepared data
BuildFolderList();
BuildFileList();
// scan filelist
ProcessFileList();
// doing work
m_copy_started = true;
m_ProgressBar.setMax(m_tocopy.size());
for (int i = 0; i < m_tocopy.size(); i++) {
try {
for (int i = 0; i < m_tocopy.size(); i++)
{
try
{
String filename = m_tocopy.get(i);
publishProgress(i);
boolean asset_size_unknown = false;
long filesize = -1;
if (m_asset_size_unknown.contains(filename)) {
if (m_asset_size_unknown.contains(filename))
{
File testme = new File(baseDir + "/" + filename);
if(testme.exists()) {
if(testme.exists())
{
filesize = testme.length();
}
asset_size_unknown = true;
}
InputStream src;
try {
try
{
src = getAssets().open(filename);
} catch (IOException e) {
Log.w("MinetestAssetCopy","Copying file: " + filename + " FAILED (not in assets)");
// TODO Auto-generated catch block
Log.e("MinetestAssetCopy","Copying file: " + filename + " FAILED (not in assets)");
e.printStackTrace();
continue;
}
......@@ -211,32 +170,38 @@ public class MinetestAssetCopy extends Activity {
int len = src.read(buf, 0, 1024);
/* following handling is crazy but we need to deal with */
/* compressed assets.Flash chips limited livetime sue to */
/* compressed assets.Flash chips limited livetime due to */
/* write operations, we can't allow large files to destroy */
/* users flash. */
if (asset_size_unknown) {
if ( (len > 0) && (len < buf.length) && (len == filesize)) {
if (asset_size_unknown)
{
if ( (len > 0) && (len < buf.length) && (len == filesize))
{
src.close();
continue;
}
if (len == buf.length) {
if (len == buf.length)
{
src.close();
long size = getFullSize(filename);
if ( size == filesize) {
if ( size == filesize)
{
continue;
}
src = getAssets().open(filename);
len = src.read(buf, 0, 1024);
}
}
if (len > 0) {
if (len > 0)
{
int total_filesize = 0;
OutputStream dst;
try {
try
{
dst = new FileOutputStream(baseDir + "/" + filename);
} catch (IOException e) {
Log.w("MinetestAssetCopy","Copying file: " + baseDir +
Log.e("MinetestAssetCopy","Copying file: " + baseDir +
"/" + filename + " FAILED (couldn't open output file)");
e.printStackTrace();
src.close();
......@@ -245,43 +210,196 @@ public class MinetestAssetCopy extends Activity {
dst.write(buf, 0, len);
total_filesize += len;
while ((len = src.read(buf)) > 0) {
while ((len = src.read(buf)) > 0)
{
dst.write(buf, 0, len);
total_filesize += len;
}
dst.close();
Log.w("MinetestAssetCopy","Copied file: " + m_tocopy.get(i) + " (" + total_filesize + " bytes)");
Log.v("MinetestAssetCopy","Copied file: " +
m_tocopy.get(i) + " (" + total_filesize +
" bytes)");
}
else if (len < 0) {
Log.w("MinetestAssetCopy","Copying file: " + m_tocopy.get(i) + " failed, size < 0");
else if (len < 0)
{
Log.e("MinetestAssetCopy","Copying file: " +
m_tocopy.get(i) + " failed, size < 0");
}
src.close();
} catch (IOException e) {
Log.w("MinetestAssetCopy","Copying file: " + m_tocopy.get(i) + " failed");
}
catch (IOException e)
{
Log.e("MinetestAssetCopy","Copying file: " +
m_tocopy.get(i) + " failed");
e.printStackTrace();
}
}
return "";
}
protected void onProgressUpdate(Integer... progress) {
if (m_copy_started) {
/**
* update progress bar
*/
protected void onProgressUpdate(Integer... progress)
{
if (m_copy_started)
{
m_ProgressBar.setProgress(progress[0]);
m_Filename.setText(m_tocopy.get(progress[0]));
}
else {
else
{
m_Filename.setText("scanning " + m_Foldername + " ...");
}
}
protected void onPostExecute (String result) {
/**
* check al files and folders in filelist
*/
protected void ProcessFileList()
{
String FlashBaseDir =
Environment.getExternalStorageDirectory().getAbsolutePath();
Iterator itr = m_filenames.iterator();
while (itr.hasNext())
{
String current_path = (String) itr.next();
String FlashPath = FlashBaseDir + "/" + current_path;
if (isAssetFolder(current_path))
{
/* store information and update gui */
m_Foldername = current_path;
publishProgress(0);
/* open file in order to check if it's a folder */
File current_folder = new File(FlashPath);
if (!current_folder.exists())
{
if (!current_folder.mkdirs())
{
Log.e("MinetestAssetCopy","\t failed create folder: " +
FlashPath);
}
else
{
Log.v("MinetestAssetCopy","\t created folder: " +
FlashPath);
}
}
continue;
}
/* if it's not a folder it's most likely a file */
boolean refresh = true;
File testme = new File(FlashPath);
long asset_filesize = -1;
long stored_filesize = -1;
if (testme.exists())
{
try
{
AssetFileDescriptor fd = getAssets().openFd(current_path);
asset_filesize = fd.getLength();
fd.close();
}
catch (IOException e)
{
refresh = true;
m_asset_size_unknown.add(current_path);
Log.e("MinetestAssetCopy","Failed to open asset file \"" +
FlashPath + "\" for size check");
}
stored_filesize = testme.length();
if (asset_filesize == stored_filesize)
{
refresh = false;
}
}
if (refresh)
{
m_tocopy.add(current_path);
}
}
}
/**
* read list of folders prepared on package build
*/
protected void BuildFolderList()
{
try
{
InputStream is = getAssets().open("index.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null)
{
m_foldernames.add(line);
line = reader.readLine();
}
is.close();
} catch (IOException e1)
{
Log.e("MinetestAssetCopy","Error on processing index.txt");
e1.printStackTrace();
}
}
/**
* read list of asset files prepared on package build
*/
protected void BuildFileList()
{
long entrycount = 0;
try
{
InputStream is = getAssets().open("filelist.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null)
{
m_filenames.add(line);
line = reader.readLine();
entrycount ++;
}
is.close();
}
catch (IOException e1)
{
Log.e("MinetestAssetCopy","Error on processing filelist.txt");
e1.printStackTrace();
}
}
protected void onPostExecute (String result)
{
finish();
}
protected boolean isAssetFolder(String path)
{
return m_foldernames.contains(path);
}
boolean m_copy_started = false;
String m_Foldername = "media";
Vector<String> m_foldernames;
Vector<String> m_filenames;
Vector<String> m_tocopy;
Vector<String> m_asset_size_unknown;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment