【问题标题】:Android - how to do background threading properly?Android - 如何正确执行后台线程?
【发布时间】:2010-01-25 16:55:53
【问题描述】:

想知道是否有人可以帮助我处理 Android 上的后台线程。

我有一段代码从设备的麦克风录制,然后通过耳机播放它录制的内容(在 1.5 上)。

我正在尝试在线程中运行它,但未能成功地将其作为后台线程运行。

当前它运行并锁定活动,因此所有发生的事情都是线程正在运行并且 UI 被锁定或似乎挂起。

这是我尝试过的最新方法:

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;
              }
      }
}

我想知道是否有人可以指导我如何将其变成后台线程?或者可能会指出一些我可能错过的相关教程?

提前致谢

【问题讨论】:

    标签: android audio multithreading background


    【解决方案1】:

    尝试调用 record.start() 而不是 .run()。

    来自Java API Docs

    start() 使该线程开始 执行; Java虚拟机 调用该线程的run方法。

    您可能还想查看AsyncTask

    【讨论】:

    • 谢谢,整理好了。但这是将其作为后台线程或工作线程运行的正确方法吗?
    • 这是一种方法。您可以通过实现 Thread 或 Runnable 以 Java 方式执行此操作,也可以通过实现 AsyncTask 以 Android 方式执行此操作。我个人将 AsyncTask 用于我在应用程序中实现的所有后台线程。
    • 感谢 mBaird,将研究 AsyncTask
    【解决方案2】:

    你不应该调用 Thread.run,调用 Thread.start

    public void run()

    如果这个线程是 使用单独的 Runnable 构造 运行对象,然后是 Runnable 对象的run方法被调用; 否则,这个方法什么也不做 并返回。

    【讨论】:

    • 谢谢 Nikola,那么我是否必须实现 runnable 以使其成为后台线程?
    • 在许多情况下,是的,您将在线程构造函数中提供一个 Runnable 对象,或者您将在线程子类中覆盖/实现 run() 方法。第三种选择是创建一个 HandlerThread 并通过其 Handler() 向其发布消息。
    猜你喜欢
    • 2016-08-21
    • 2019-06-27
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    相关资源
    最近更新 更多