Как создать класс индикатора выполнения, который загружает файлы разных типов из папок / res и / assets в Android? - PullRequest
0 голосов
/ 03 апреля 2012

Вот ядро ​​моего класса ProgressBar:

package nttu.edu.activities;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;

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.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;

public class NewLoadingActivity extends Activity
{
    private ProgressBar bar;
    private AssetManager assetManager;
    private Load loading;

    private class Load
    {
        public Stack<byte[]> stack;
        public Stack<Bitmap> results;
        public Handler handler;
        public int totalByteSize;
        public int currentByteSize;

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

        public Load()
        {
            stack = new Stack<byte[]>();
            results = new Stack<Bitmap>();
            handler = new Handler();
            totalByteSize = 0;
            currentByteSize = 0;
        }

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

        public void startHandler()
        {
            handler.post(new Runnable()
            {
                public void run()
                {
                    while (currentByteSize < totalByteSize)
                    {
                        try
                        {
                            Thread.sleep(1000);
                            bar.setProgress(currentByteSize);
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }

        public void startLoad(){
            while (stack.size() > 0){
                byte[] bytes = (byte[]) stack.pop();
                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                if (bitmap != null)
                    currentByteSize += bytes.length;
                results.push((Bitmap) bitmap);
            }
            sort();
            finish();
        }

        //This is the place to load specific assets into a class.
        private void sort(){
            Art.sprites = (Bitmap) results.pop();
        }

        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();
        loading = new Load();
        //bar = new ProgressBar(this);
        bar = (ProgressBar) this.findViewById(R.id.loadingBar);
        loading.loadBar();
        loading.startHandler();
        loading.startLoad();
    }

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

Пока что я могу загружать только растровые изображения, добавляя их пути в функцию sort ().

Причина, по которой я могу толькозагрузка растровых изображений заключается в том, что я не знаю, как различать загрузку растровых изображений, загрузку звука и загрузку ресурсов, но я хотел поместить все необходимое для загрузки в один большой класс.Я просто не знаю, как их разбить.

Я попытался разбить нужные файлы по именам каталогов или отсортировать их по собственным подкаталогам, например:

Snippet of the /assets folder's subdirectories

Но тогда я застрял бы в поиске нового решения для рекурсивного списка каталогов и прочего, и все равно не смог бы это исправить.Я занимался этой проблемой последние 2 дня, но ничего не вышло.

Вот мой результат, чтобы доказать, что я действительно делал свою домашнюю работу:

    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.");
    }
}

Я продолжаю больше изучать вопрос о том, как разделить файлы разных типов на экране загрузки, но по переполнению стека нет никаких вопросов относительно того, как загружать разные файлы в целом.

После этого я решил придумать простой, грубый и плохой ответ на этот вопрос, а именно создать все ресурсы в растровых изображениях и пожертвовать звуковыми файлами для игрового приложения.И, честно говоря, я не хочу этого делать.

Пожалуйста, помогите мне, например, дайте мне советы, подсказки или все, что у вас есть в рукавах.Что я должен сделать, чтобы загрузить все типы файлов в моем индикаторе выполнения?Что мне нужно искать?

Заранее спасибо.

1 Ответ

0 голосов
/ 08 июля 2012

Вот как создать ProgressBar для произвольных файлов.

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();
    }
}
...