1. 程式人生 > >Android學習 第十一周

Android學習 第十一周

andro ani back stop 方法 app 消息 handler int

第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學習 第十一周