Android学习 第十一周

第44章

使用MediaRecord录音

实现代码:

//布局代码:activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_control"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始录音" />

</RelativeLayout>
MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private Button btn_control;
    private boolean isStart = false;
    private MediaRecorder mr = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_control = (Button) findViewById(R.id.btn_control);
        btn_control.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!isStart){
                    startRecord();
                    btn_control.setText("停止录制");
                    isStart = true;
                }else{
                    stopRecord();
                    btn_control.setText("开始录制");
                    isStart = false;
                }
            }
        });
    }

    //开始录制
    private void startRecord(){
        if(mr == null){
            File dir = new File(Environment.getExternalStorageDirectory(),"sounds");
            if(!dir.exists()){
                dir.mkdirs();
            }
            File soundFile = new File(dir,System.currentTimeMillis()+".amr");
            if(!soundFile.exists()){
                try {
                    soundFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            mr = new MediaRecorder();
            mr.setAudioSource(MediaRecorder.AudioSource.MIC);  //音频输入源
            mr.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);   //设置输出格式
            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);   //设置编码格式
            mr.setOutputFile(soundFile.getAbsolutePath());
            try {
                mr.prepare();
                mr.start();  //开始录制
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    //停止录制,资源释放
    private void stopRecord(){
        if(mr != null){
            mr.stop();
            mr.release();
            mr = null;
        }
    }
}

最后在AndroidManifest.xml中添加下述权限:


第45章

Handler消息传递机制浅析

本节讲解的 是Activity中UI组件中的信息传递Handler。Android为了线程安全,并不允许我们在UI线程外操作UI;很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUiThread()来更新,甚至更高级的事务总线,当然,这里我们只学习Handler,什么是Handler,执行流程,相关方法,子线程与主线程中中使用Handler的区别等。

相关名词

  • UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
  • Handler:作用就是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象
  • Message:Handler接收与处理的消息对象
  • MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
  • Looper:每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!

Handler的相关方法

  • void handleMessage(Message msg):处理消息的方法,通常是用于被重写!
  • sendEmptyMessage(int what):发送空消息
  • sendEmptyMessageDelayed(int what,long delayMillis):指定延时多少毫秒后发送空信息
  • sendMessage(Message msg):立即发送信息
  • sendMessageDelayed(Message msg):指定延时多少毫秒后发送信息
  • final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 如果是参数为(int what,Object object):除了判断what属性,还需要判断Object属性是否为指定对象的消息

Handler使用实例

实现代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:id="@+id/RelativeLayout1"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:gravity="center"  
    tools:context="com.jay.example.handlerdemo1.MainActivity" >  

    <ImageView  
        android:id="@+id/imgchange"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentLeft="true"  
        android:layout_alignParentTop="true" />  

</RelativeLayout> 
MainActivity.java:

public class MainActivity extends Activity {  

    //定义切换的图片的数组id  
    int imgids[] = new int[]{  
        R.drawable.s_1, R.drawable.s_2,R.drawable.s_3,  
        R.drawable.s_4,R.drawable.s_5,R.drawable.s_6,  
        R.drawable.s_7,R.drawable.s_8  
    };  
    int imgstart = 0;  

    final Handler myHandler = new Handler()  
    {  
      @Override  
      //重写handleMessage方法,根据msg中what的值判断是否执行后续操作  
      public void handleMessage(Message msg) {  
        if(msg.what == 0x123)  
           {  
            imgchange.setImageResource(imgids[imgstart++ % 8]);  
           }  
        }  
    };  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        final ImageView imgchange = (ImageView) findViewById(R.id.imgchange);  

        //使用定时器,每隔200毫秒让handler发送一个空信息  
        new Timer().schedule(new TimerTask() {            
            @Override  
            public void run() {  
                myHandler.sendEmptyMessage(0x123);  

            }  
        }, 0,200);  
    }  

} 

第46章要点

AsyncTask类

  • android.os.AsyncTask类是一个工具类,它使得处理后台进程以及将进度更新发布到UI线程更加容易。
  • 这个类专门用于持续最多数秒钟的较短的操作,对于长时间运行的后台任务,应该使用Java并发工具框架。
  • AsyncTask类带有一组公有的方法和一组受保护的方法。公有方法用于执行和取消其任务。execute方法启动一个异步的操作,而cancel方法取消该操作。受保护的方法是供你在子类中覆盖的。doInBackground方法就是一个受保护的方法,它是该类中最重要的方法,并且为异步操作提供了逻辑。
  • publishProgress方法,也是受保护的方法,它通常从doInBackground中调用多次,通常在该方法中编写代码更新一个进度条或其他UI组件。

Android学习 第十一周

上一篇:java注解演示 映射生成表 示例 来自thinking in java 4 20章部分代码


下一篇:C++的const关键词的一些注记