第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组件。