简体   繁体   中英

Is there an efficient way to check for subdirectories and load assets via relative path in Android asset folder?

Here's my code, albeit very rough coding:

public void loadStack(AssetManager manager, String path) {
            String[] list;
            String thePath;
            try {
                list = manager.list(path);
                if (list != null) {
                    for (int i = 0; i < list.length; i++) {
                        try {
                            if (list.length != 0) {
                                if (path.toString() == "") loadStack(manager, list[i]);
                                else {
                                    thePath = path + "/" + list[i];
                                    loadStack(manager, thePath);
                                }
                            }
                            String[] test = manager.list(list[i]);
                            if (test.length != 0) {
                                for (int j = 0; j < test.length; j++) {
                                    byte[] assetBytes = readFromStream(list[i] + "/" + test[j]);
                                    assetStack.push(assetBytes);
                                    totalByteSize += assetBytes.length;
                                    Log.d("Loading", "Stack loads assetBytes of length: " + Integer.toString(assetBytes.length));
                                    // totalStackElementSize = assetStack.size();
                                }
                            }
                            // loadStack(manager, path + "/" + list[i]);
                        }
                        catch (IOException e) {
                            continue;
                        }
                    }
                }
            }
            catch (IOException e1) {
                return;
            }
        }

I'm still trying to improve the code, and all I'm lacking is telling apart what relative paths are subdirectories, and what relative paths are actual paths to files needed to load.

That way, I can rely on using a recursive method to walk through each and every subdirectories of the asset folder, and load only the ones I need.

Can anyone point me to the right direction? Or there's something I'm missing out on the AssetManager documentation? Thanks in advance. I'm doing the best I can so far.

UPDATE:

Improved my code to this:

public void loadStack(AssetManager manager, String path, int level) {
            try {
                String[] list = manager.list(path);
                if (list != null) {
                    for (int i = 0; i < list.length; i++) {
                        if (level >= 1) loadStack(manager, path + "/" + list[i], level + 1);
                        else if (level == 0) loadStack(manager, list[i], level + 1);
                        else {
                            byte[] byteBuffer = readFromStream(path);
                            assetStack.push(byteBuffer);
                            totalByteSize += byteBuffer.length;
                        }
                    }
                }
            }
            catch (IOException e) {
                Log.e("Loading", "Occurs in AssetLoad.loadStack(AssetManager, String, int), file can't be loaded: " + path);
                throw new RuntimeException("Couldn't load the files correctly.");
            }
        }   

I'm still trying to improve my code. The only problem is that it tends to read folders I haven't added to the assets folder, or folders I never created before. Those causes logic errors, which I'm avoiding as much as possible.

This is a specific answer to a vague question, however, it works the same way.

package nttu.edu.activities;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Queue;

import nttu.edu.R;
import nttu.edu.graphics.Art;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;

public class NewLoadingActivity extends Activity {
    public ProgressBar bar;
    private AssetManager assetManager;
    public Handler handler;
    public ProgressTask task;

    private final String[] list = {
    // Art.sprites
    "art/sprites.png" };

    private class ProgressTask extends AsyncTask<Void, Void, Void> {
        public int totalByteSize;
        public int currentByteSize;
        public Queue<Bitmap> bitmapQueue;
        public Queue<byte[]> byteQueue;

        public ProgressTask() {
            totalByteSize = 0;
            currentByteSize = 0;
            bitmapQueue = new LinkedList<Bitmap>();
            byteQueue = new LinkedList<byte[]>();
        }

        public void onPostExecute(Void params) {
            Art.sprites = bitmapQueue.remove();
            finish();
        }

        public void onPreExecute() {
            try {
                for (int i = 0; i < list.length; i++) {
                    byte[] bytes = readFromStream(list[i]);
                    totalByteSize += bytes.length;
                    byteQueue.add(bytes);
                }
                bar.setMax(totalByteSize);
            }
            catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public void onProgressUpdate(Void... params) {
            bar.setProgress(currentByteSize);
        }

        @Override
        protected Void doInBackground(Void... params) {
            while (currentByteSize < totalByteSize) {
                try {
                    Thread.sleep(1000);
                    if (byteQueue.size() > 0) {
                        byte[] bytes = byteQueue.remove();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                        bitmapQueue.add(bitmap);
                        currentByteSize += bytes.length;
                        this.publishProgress();
                    }
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        private byte[] readFromStream(String path) throws IOException {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length = 0;
            InputStream input = assetManager.open(path);
            while (input.available() > 0 && (length = input.read(buffer)) != -1)
                output.write(buffer, 0, length);
            return output.toByteArray();
        }

    }

    public void onCreate(Bundle b) {
        super.onCreate(b);
        this.setContentView(R.layout.progressbar);
        assetManager = this.getAssets();
        handler = new Handler();
        task = new ProgressTask();
        bar = (ProgressBar) this.findViewById(R.id.loadingBar);
        if (bar == null) throw new RuntimeException("Failed to load the progress bar.");
        task.execute();
    }

    public void finish() {
        Intent intent = new Intent(this, MenuActivity.class);
        intent.putExtra("Success Flag", Art.sprites != null);
        this.setResult(RESULT_OK, intent);
        super.finish();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM