2013-04-12 2 views
0

폴더의 사운드 파일 목록보기에서 파일의 길이 (초)를 표시하려고합니다. 내가 취하는 단계 :WAV 파일 길이가 초 단위로 계산되어 앱이 느려짐

  1. 먼저 soundFiles의 인스턴스에 대한 ArrayList를 만듭니다.
  2. 그런 다음 for 루프에서 soundFile.setLength (calculateLength (file [i]))에 의해 인스턴스에 데이터를 추가합니다.
  3. 이렇게하면 CustomArrayAdapter가 시작되어 listView에 적용됩니다.
  4. 내 CustomArrayAdapter에서이를 적용합니다 : tvFileLength.setText (soundFile.getLength()); (whith 홀더 비록 ..)

그러나 내가 이것을하고 있기 때문에, 내 애플은 거북이보다 느립니다! (400 파일을 가지고) 이 속도를 고칠 수있는 방법이 있습니까? 나는 데

private int calculateLength(File yourFile) 
      throws IllegalArgumentException, IllegalStateException, IOException { 
     MediaPlayer mp = new MediaPlayer(); 
     FileInputStream fs; 
     FileDescriptor fd; 
     fs = new FileInputStream(yourFile); 
     fd = fs.getFD(); 
     mp.setDataSource(fd); 
     mp.prepare(); 
     int length = mp.getDuration(); 
     length = length/1000; 
     mp.release(); 
     return length; 

    } 

**EDIT** 

새로운 코드 :

활동

myList = new ArrayList<RecordedFile>(); 

     File directory = Environment.getExternalStorageDirectory(); 
     file = new File(directory + "/test/"); 

     File list[] = file.listFiles(); 

     for (int i = 0; i < list.length; i++) { 
      if (checkExtension(list[i].getName()) == true) { 

       RecordedFile q = new RecordedFile(); 
       q.setTitle(list[i].getName()); 
       q.setFileSize(readableFileSize(list[i].length())); 
          //above is the size in kB, is something else but I 
          //also might move this to the AsyncTask! 


       myList.add(q); 
      } 
     } 
     new GetAudioFilesLength(myList).execute(); 

AsyncTask를

List<RecordedFile> mFiles = new ArrayList<RecordedFile>(); 

    public GetAudioFilesLength(List<RecordedFile> theFiles) { 
     mFiles = theFiles; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 

     File directory = Environment.getExternalStorageDirectory(); 
     // File file = new File(directory + "/test/"); 
     String mid = "/test/"; 

     for (RecordedFile fileIn : mFiles) { 

      File file = new File(directory + mid + fileIn.getTitle()); 
      try { 
       int length = readableFileLengthSeconds(file); 
       fileIn.setFileLengthSeconds(length); 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalStateException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      // Do something with the length 


      // You might want to update the UI with the length of this file 
      // with onProgressUpdate so that you display the length of the files 
      // in real time as you process them. 
     } 
     return mid; 

    } 

    @Override 
    protected void onProgressUpdate(Void... values) { 

    } 

    @Override 
    protected void onPostExecute(String result) { 
     // Update the UI in any way you want. You might want 
     // to store the file lengths somewhere and then update the UI 
     // with them here 
    } 

    /* 
    * @Override protected void onPreExecute() { } 
    */ 

    public int readableFileLengthSeconds(File yourFile) 
      throws IllegalArgumentException, IllegalStateException, IOException { 
     MediaPlayer mp = new MediaPlayer(); 
     FileInputStream fs; 
     FileDescriptor fd; 
     fs = new FileInputStream(yourFile); 
     fd = fs.getFD(); 
     mp.setDataSource(fd); 
     mp.prepare(); // might be optional 
     int length = mp.getDuration(); 
     length = length/1000; 
     mp.release(); 
     return length; 

    } 

아 esome, 그것은 부분적으로 작동하지만,! 남은 질문이 2 개 남았습니다.

  1. 괜찮습니까?
  2. 그것은 내 listview의 첫 번째 100 요소를 말할 수 있습니다, 그 후에 그것은 0 s를 표시합니다, 내가 생각하는 onProgressUpdate와 관련이 있습니다,하지만 어떻게이 일을 할 수 있는지 모르겠습니다.

답변

1

MediaPlayer에서 재생 시간을 찾을 수 있도록 파일을 읽는 데 시간이 걸립니다. UI 스레드에서이 작업을 실행하면 전체 응용 프로그램의 속도가 느려집니다.

프로세스 속도를 높이는 방법에 대한 제안은 없지만 AsyncTask가있는 백그라운드 스레드에서이 작업을 수행하면 응용 프로그램이 훨씬 부드럽게 작동 할 수 있습니다. 이 같은 그 보일 수 있습니다 무언가 : 당신이 처리를 시작할 때

private class GetAudioFilesLength extends AsyncTask<Void, Void, Void> { 

     List<File> mFiles = new ArrayList<File>(); 

     public GetAudioFilesLength(List<File> theFiles){ 
      mFiles = theFiles; 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      for(File file : mFiles){ 
       int length = calculateLength(file); 
       // Do something with the length 

       // You might want to update the UI with the length of this file 
       // with onProgressUpdate so that you display the length of the files 
       // in real time as you process them. 
      } 
     }  

     @Override 
     protected void onPostExecute(String result) { 
      // Update the UI in any way you want. You might want 
      // to store the file lengths somewhere and then update the UI 
      // with them here 
     } 

     @Override 
     protected void onPreExecute() { 
     } 

     @Override 
     protected void onProgressUpdate(Void... values) { 
     } 
} 

, 단지 new GetAudioFilesLength(files).execute()

편집 전화는 추가 질문에 대답 :

  1. 그것은 원래의 코드로 효율적 보인다 . 현재 차이점은 작업이 백그라운드 스레드에서 수행되므로 사용자가 응용 프로그램과 계속 상호 작용할 수 있다는 것입니다. 오디오 파일의 길이를 더 효율적으로 읽을 수있는 방법이있을 수 있지만 그게 무엇인지는 알 수 없습니다. 샘플 속도와 인코딩을 알고 있다면 MediaPlayer에로드하지 않고 오디오의 길이를 계산하는 코드를 작성하는 것이 더 오래 걸릴 수 있습니다. 다시 한번 말하지만, 다른 누군가가 도와야합니다.

  2. 문제가 무엇인지 알 수 없지만 onProgressUpdate를 사용하여 UI를 업데이트하고 ListView에 길이를 추가하는 방법을 묻는 것으로 생각됩니다.

당신은 그에 따라 UI를 업데이트 할 수있는 문자열 (또는 뭔가 다른) doInBackground에서 AsyncTask<Void, String, Void>, that tells onProgressUpdate what you will be passing to it. You can then call publishProgress` 될하기 위해 AsyncTask를 생성에 중간 인수를 변경할 수 있습니다.

@Override 
    protected String doInBackground(Void... params) { 
     for(File file : mFiles){ 
      int length = calculateLength(file); 
      // Do something with the length 

      // You might want to update the UI with the length of this file 
      // with onProgressUpdate so that you display the length of the files 
      // in real time as you process them. 
      publishProgress("The length of " + file.getName() + " is: " + length); 
     } 
    }  

    @Override 
    protected void onPostExecute(Void result) { 
     // Update the UI in any way you want. You might want 
     // to store the file lengths somewhere and then update the UI 
     // with them here 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     // You'll have to implement whatever you'd like to do with this string on the UI 
     doSomethingWithListView(values[0]); 
    } 
+0

감사합니다. @ mattgmg1990, 감사합니다. 오늘 저녁이나 오늘 저녁에 다시 시도해 드리겠습니다. –

+0

문제 없습니다, 어떻게 진행되는지 알려주세요! – mattgmg1990

+0

나는 그것을 밖으로 시도, 두 가지 질문 왼쪽 @ mattgmg1990, 나는 내 질문을 편집 :) 감사합니다 남자! –