我有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项目中呢?
答案 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);
}
}