mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Speedup initial android startup on some devices by factor 10 or more
This commit is contained in:
parent
aaec558f85
commit
35149a10e3
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user