Прогрессбар не двигается

У меня есть аудио приложение, которое воспроизводит / записывает образцы. Я поместил индикатор прогресса в пользовательский интерфейс, но при воспроизведении семпла полоса не перемещается или не увеличивается с семплом. как мне заставить его двигаться?

mProgress = (ProgressBar) findViewById(R.id.progressBar1);
            // final long trackDuration = (musicLength/44100)*1000; // track duration in millisec

             // Start lengthy operation in a background thread
             new Thread(new Runnable() {
                 public void run() {
                     //Log.i("music length = ", trackDuration+"");

                     while (mProgressStatus < musicLength) {
                         mProgressStatus = audioTrack.write(music, 0, musicLength);

                         // Update the progress bar
                         mHandler.post(new Runnable() {
                             public void run() {
                                 mProgress.setProgress(mProgressStatus);

                             }
                         });
                     }
                 }
             }).start();

3 ответа

Решение

Как предполагает Хакан, вам необходимо выполнить все обновления пользовательского интерфейса в потоке пользовательского интерфейса. Так как у вас уже есть Handlerнужно просто переопределить handleMessage() метод и выполнить обновление вашего пользовательского интерфейса там. Ваш код станет что-то вроде:

private static final int PROGRESS_UPDATE = 0;
...
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
// final long trackDuration = (musicLength/44100)*1000; // track duration in millisec

// Start lengthy operation in a background thread
new Thread(new Runnable() {
    public void run() {
        //Log.i("music length = ", trackDuration+"");

        while (mProgressStatus < musicLength) {
            mProgressStatus = audioTrack.write(music, 0, musicLength);

            // Update the progress bar
            Message msg = Message.obtain();
            msg.what = PROGRESS_UPDATE;
            msg.arg1 = mProgressStatus;
            mHandler.sendMessage(msg);
        }
    }
}).start();
...
Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what){
        case PROGRESS_UPDATE:
            mProgress.setProgress(msg.arg1);
            break;
        default:
            Log.e("MyTag","Unsupported message type");
            break;
        }
    }
}

хорошо, спасибо за это dave.c. Я перешел из режима пропаривания в статический. Я также записал данные на трек перед вызовом play на треке. я вызвал play в runnable, который обрабатывает обновление индикатора выполнения. приложение воспроизводит аудиосэмпл, но индикатор выполнения по-прежнему не двигается. Я выложу код ниже, который показывает изменения. есть идеи, почему индикатор прогресса не двигается?

// Get the length of the audio stored in the file (16 bit so 2 bytes per short)
        // and create a short array to store the recorded audio.
        musicLength = (int)(file.length()/2);
        final short[] music = new short[musicLength];
        Log.i("filename length", file.length()+""+file.getName());

        try {



        // Create a DataInputStream to read the audio data back from the saved file.
        InputStream is = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(is);
        DataInputStream dis = new DataInputStream(bis);

        // Read the file into the music array.
        int i = 0;
        while (dis.available() > 0) {
        //music[musicLength-1-i] = dis.readShort();
          music[i] = dis.readShort();

        i++;
        }
        Log.i("buffer with "+ file.getName(), music.length+" passed in from array");

        // Close the input streams.
        dis.close();


        // Create a new AudioTrack object using the same parameters as the AudioRecord
        // object used to create the file.
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
        44100,
        AudioFormat.CHANNEL_CONFIGURATION_MONO,
        AudioFormat.ENCODING_PCM_16BIT,
        musicLength,
        AudioTrack.MODE_STATIC);

        Log.i("audio instance = ", ""+audioTrack.getState());

        // Start playback
        //audioTrack.play();






             mProgress = (ProgressBar) findViewById(R.id.progressBar1);
            // final long trackDuration = (musicLength/44100)*1000; // track duration in millisec

             // Start lengthy operation in a background thread
             new Thread(new Runnable() {
                 public void run() {
                     //Log.i("music length = ", trackDuration+"");

                     while (mProgressStatus < musicLength) {

                         mProgressStatus = audioTrack.write(music, 0, musicLength);

                         // Update the progress bar
                         mHandler.post(new Runnable() {
                             public void run() {
                                 audioTrack.play();
                                 mProgress.setProgress(mProgressStatus);


                             }
                         });

                         Message msg = Message.obtain();
                         msg.what = PROGRESS;
                         msg.arg1 = mProgressStatus;
                         mHandler.sendMessage(msg);





                     }
                 }
             }).start();

             mHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        switch(msg.what){
                        case PROGRESS:
                            mProgress.setProgress(msg.arg1);

                            break;
                        default:
                        Log.e("MyTag","Unsupported message type");
                            break;
                        }

                    }

             };




        } catch (Exception e) {
            e.printStackTrace();
        Log.e("AudioTrack","Playback Failed");
        }

    }

Рекомендуется использовать AsyncTask замешан в жонглировании потоками и обработчиками. Он содержит необходимые потоки и метод обработчика. onProgressUpdate вызывается в потоке пользовательского интерфейса (после каждого publishProgress звоните), чтобы он мог успешно обновить ваш индикатор.

Вам нужно обновлять индикатор выполнения в потоке пользовательского интерфейса (который является основным потоком класса активности), а не через другие потоки. Вам необходимо создать обработчик в потоке пользовательского интерфейса и отправлять сообщения этому обработчику другими вашими потоками. У Android есть пример этого, когда они создают ProgressDialog. Не забудьте развернуть раздел внизу, в котором показан "Пример ProgressDialog со вторым потоком", поскольку это объясняет мой ответ на примере.

Другие вопросы по тегам