将许多资产有效地加载到android项目中

时间:2016-01-14 08:34:59

标签: android performance

我有231个声音文件(持续时间〜每秒0.2秒),总大小为5.7 MB加载到我的android项目中。我正在尝试在应用程序开始使用for循环时加载它们,如

for (int i = 0; i < 231; i++){
    ...
    loadSoundAsset(i);    //method to load the sound files
    i++;
    ...     
}

然而上述方法加载声音文件的时间太长。如何将有效的许多资产文件加载到android项目中呢?

1 个答案:

答案 0 :(得分:1)

我为您创建示例代码。如何加快速度? (我测试了大约180个声音文件的资产文件。)

  

MainActivity

public class MainActivity extends Activity implements TaskListener {

    MultiLoader loader = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView view = new TextView(this);
        view.setText("Loader");
        setContentView(view);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        loader = new MultiLoader(this, this);
        loader.load("sound");
    }

    @Override
    public void onTaskEnd() {
        Vector<byte[]> soundDatas = loader.getData();
        Log.e("MainActivity", "TaskEnd");
    }

    @Override
    protected void onDestroy() {
        loader.clear();
        super.onDestroy();
    }

}
  

MultiLoader

package com.fastload;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import java.util.regex.Pattern;

import android.content.Context;
import android.util.Log;

public class MultiLoader {

    private int threadCount = 0;
    private String[] mFiles;

    private Vector<byte[]> fileContents = new Vector<byte[]>();
    private Thread[] mQueue = null;
    private Context mContext;
    private TaskListener listener;

    public MultiLoader(Context mContext, TaskListener listener) {
        super();
        this.mContext = mContext;
        this.listener = listener;
    }

    public Vector<byte[]> getData(){
        return fileContents;
    }

    public void reQueue(int index){
        boolean status = true;
        mQueue[index] = null;
        for(Thread item : mQueue){
            status &= (item == null);
        }

        if(status){
            listener.onTaskEnd();
        }
    }

    public void load(final String path){
        initialize(path);
        if(mFiles == null || (mFiles != null && mFiles.length < 1))
            return;
        mQueue = new Thread[threadCount];
        for(int i = 0; i < threadCount; ++i){
            int len = mFiles.length;
            int piece = len / threadCount;
            final int startIndex = i * piece;
            final int endIndex = (i == threadCount - 1) ? len - startIndex - 1 : startIndex + piece;

            MyTask task = new MyTask("MyTask##"+i, i, new EndListener(){
                @Override
                public void onEnd(int index, String name) {
                    Log.e("ThreadEND", "name = "+name);
                    reQueue(index);
                }
            }) {

                @Override
                public void execute() {
                    for(int index = startIndex; index < endIndex; ++index){
                        File file = new File(mFiles[index]);
                        InputStream is = null;
                        ByteArrayOutputStream os = null;
                        byte[] data = null;
                        try {
                            is = mContext.getAssets().open(path + File.separator + file.getName());
                            os = new ByteArrayOutputStream();

                            int count = 0;
                            byte[] buffer = new byte[1024];
                            while((count = is.read(buffer)) > 0){
                                os.write(buffer, 0, count);
                            }
                            os.flush();
                            data = os.toByteArray();
                            debug(getName(), index, path + File.separator + file.getName());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally{
                            if(is != null){
                                try {
                                    is.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }

                            if(os != null){
                                try {
                                    os.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }

                        }

                        if(data != null){
                            add(data);
                        }

                    }
                }

            };
            mQueue[i] = task;
            task.start();

        }
    }

    private void debug(String who, int index, String name){
        Log.e("MULTI LOADER DEBUG", "who = "+who+" , name = "+name+", index = "+index);
    }

    private void initialize(String path){
        threadCount = getNumCores() * 2;
        try {
            mFiles = mContext.getAssets().list(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void add(byte[] data){
        synchronized (fileContents) {
            fileContents.add(data);
        }
    }

    private void remove(byte[] data){
        synchronized (fileContents) {
            fileContents.remove(data);
        }
    }

    public void clear(){
        synchronized (fileContents) {
            fileContents.clear();
        }
    }

    private int getNumCores() {
        class CpuFilter implements FileFilter {
            @Override
            public boolean accept(File pathname) {
                if(Pattern.matches("cpu[0-9]+", pathname.getName())) {
                    return true;
                }
                return false;
            }      
        }

        try {
            File dir = new File("/sys/devices/system/cpu/");
            File[] files = dir.listFiles(new CpuFilter());
            return files.length;
        } catch(Exception e) {
            return 1;
        }
    }

    private abstract class MyTask extends Thread{

        private EndListener listener;
        private int index;

        private MyTask() { }

        public MyTask(String threadName, int index, EndListener listener) {
            super(threadName);
            this.index = index;
            this.listener = listener;
        }

        public abstract void execute();

        @Override
        public void run() {
            execute();
            end();
        }

        public void end(){
            listener.onEnd(index, getName());
        }

        public int getIndex(){
            return index;
        }

    }

    public interface TaskListener{
        public void onTaskEnd();
    }

    public interface EndListener{
        public void onEnd(int index, String name);
    }

}