Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - how to do background threading properly?

Was wondering if anyone could help me on background threading on Android.

I have a piece of code that records from the mic of the device and then plays back what it records through the ear piece(on 1.5).

I am trying to run it in a thread but have been unsuccessful in getting it to run as a background thread.

Currently it runs and locks up the activity so that all thats happening is the thread is running and the UI is locked up or appears to be hanging.

Here is the lastest way I tried to do it:

public class LoopProg extends Activity {


boolean isRecording; //currently not used

  public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);

   AudioManager audio_service = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

   audio_service.setSpeakerphoneOn(false);
   audio_service.setMode(AudioManager.MODE_IN_CALL);
   audio_service.setRouting(AudioManager.MODE_NORMAL,
   AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL);

   Record record = new Record();  
   record.run();

 }

  public class Record extends Thread
  {


          static final int bufferSize = 200000;
          final short[] buffer = new short[bufferSize];
          short[] readBuffer = new short[bufferSize];

          public void run() {  
            isRecording = true;
            android.os.Process.setThreadPriority
            (android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

            int buffersize = AudioRecord.getMinBufferSize(11025,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

                           AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                           11025,
                                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                           AudioFormat.ENCODING_PCM_16BIT,
                                           buffersize);

                           AudioTrack atrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
                                           11025,
                                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                           AudioFormat.ENCODING_PCM_16BIT,
                                           buffersize,
                                           AudioTrack.MODE_STREAM);

                           setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);


                           atrack.setPlaybackRate(11025);

                           byte[] buffer = new byte[buffersize];
                           arec.startRecording();
                           atrack.play();

                           while(isRecording) {
                                   arec.read(buffer, 0, buffersize);
                                   atrack.write(buffer, 0, buffer.length);
                           }

                           arec.stop();
                           atrack.stop();
                           isRecording = false;
              }
      }
}

I was wondering if anybody could guide me on how to turn this into a background thread? Or prehaps point me to some tutorial that may be relevant that I may have missed?

Thanks in advance

like image 759
Donal Rafferty Avatar asked Jan 25 '10 16:01

Donal Rafferty


People also ask

How do I run a thread in the background?

To specify the thread on which to run the action, construct the Handler using a Looper for the thread. A Looper is an object that runs the message loop for an associated thread. Once you've created a Handler , you can then use the post(Runnable) method to run a block of code in the corresponding thread.

What is the current recommended way to handle long running background tasks?

Recommended solutionScheduling deferred work through WorkManager is the best way to handle tasks that don't need to run immediately but which ought to remain scheduled when the app closes or the device restarts.


2 Answers

Try calling record.start() instead of .run().

From the Java API Docs:

start() Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

You also may want to look into AsyncTask.

like image 62
Mark B Avatar answered Oct 24 '22 10:10

Mark B


You shouldn't call Thread.run, call Thread.start

public void run()

If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.

like image 24
Nikola Smiljanić Avatar answered Oct 24 '22 11:10

Nikola Smiljanić