Android事件處理

基於監聽事件處理

1.內部類作爲事件監聽器類
2.外部類作爲事件監聽器類

較少見,不利於提高程序內聚性,外部類也不能自由訪問activity中的組件

3.Activity本身作爲事件監聽器

實現事件監聽器接口

4.匿名內部類作爲事件監聽器
5.直接綁定到標籤

onClick屬性


基於回調事件處理

爲了實現回調機制的事件處理,Android爲所有GUI組件都提供了一些事件處理的回調方法,當進行操作事件時系統會回調相應的方法

public boolean onKeyDown(int keyCode, KeyEvent event)
public boolean onKeyLongPress(int keyCode, KeyEvent event) 
public boolean onKeyShortcut(int keyCode, KeyEvent event) 
public boolean onKeyUp(int keyCode, KeyEvent event) 
public boolean onTouchEvent(MotionEvent event)
......

關於回調事件處理方法的返回值

1.返回true,表示事件已經完全被處理/消耗,該事件不會傳播出去
2.返回false,表示未完全處理該事件,該事件會傳播出去

如果既有監聽事件又有回調事件,那麼首先觸發監聽事件,接着纔會觸發回調事件


響應的系統設置事件

Configuration類:用於描述手機設備上的配置信息

frameworks/base/core/java/android/content/res/Configuration.java
Configuration config = getResources().getConfiguration();
public float fontScale; //獲取設置的字體
public int mcc; //獲取移動信號的國家碼
public int mnc; //獲取移動信號的網絡碼
public Locale locale; //獲取用戶當前的Locale
public int orientation; //獲取系統屏幕的方向

監聽系統配置信息變化

重寫Activity的onConfigurationChanged(Configuration newConfig)方法
當屏幕方向改變,語言改變..時會回調該方法


Handler消息傳遞機制

Handler類的主要作用有兩個:

1.在新啓動的線程中發送消息
2.在主線程中獲取,處理消息

與Handler一起工作的幾個組件

Message:Handler接收和處理的消息對象
Looper:每個線程只能擁有一個Looper。它的loop方法負責讀取MessageQueue中的消息,讀取到之後就把消息交給發送該消息的Handler進行處理
MessageQueue:消息隊列,它採用先進先出的方式來管理Message。程序創建Looper對象時會在它的構造器中創建Looper對象

Looper、MessageQueue、Handler作用

Looper:每個線程只能擁有一個Looper。它負責管理MessageQueue,會不斷地從MessageQueue中取出消息,將消息分給對應的Handler去處理。
MessageQueue:由Looper負責管理。它採用先進先出的方式來管理Message。
Handler:它能把消息發送給Looper管理的MessageQueue,並負責處理Looper分給它的消息。

Handler使用

// 1.主線程中創建一個Handler對象
Handler mHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg){ //處理代碼 }
};
// 2.子線程中發送消息
mHandler.sendEmptyMessage(0x1233);


異步任務(AsyncTask)

使用AsyncTask三步:

1.創建AsyncTask的子類,併爲三個泛型參數
  Params:啓動任務執行的輸入參數類型
  Progress:後臺任務完成的進度值的類型
  Result:後臺執行任務完成後返回結果的類型
2.根據需要,實現AsyncTask的方法
  doInBackground() //重寫該方法就是後臺線程將要完成的任務
  onProgressUpdate() //在doInBackground()方法中調用publishProgress更新進度後會觸發該方法
  onPreExecute() //在執行後臺耗時操作前被調用
  onPostExecute() //當doInBackground()方法完成後會自動調用該方法,並將doInBackground()返回值傳給該方法
3.調用AsyncTask子類的實例的execute(Params...params)開始執行耗時任務。

使用AsyncTask時必須遵守的規則:

1.必須在UI線程中創建AsyncTask的實例。
2.必須在UI線程中調用AsyncTask的exceute()方法。
3.AsyncTask的方法不應該由程序員代碼調用,而是由android系統負責調用
  doInBackground()/onProgressUpdate()/onPreExecute()/onPostExecute()。
4.每個AsyncTask只能被執行一次,多次調用將會引發異常。

AsyncTask Demo

/***************異步下載****************/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class AsyncTaskTest extends Activity {
    private TextView show;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        show = (TextView) findViewById(R.id.show);
    }

    // android:onClick="download"
    public void download(View source) throws MalformedURLException {
        DownTask task = new DownTask(this);
        task.execute(new URL("http://www.baidu.com"));
    }

    class DownTask extends AsyncTask<URL, Integer, String>
    {
        ProgressDialog pdialog;
        // 定義記錄已經讀取行的數量
        int hasRead = 0;
        Context mContext;

        public DownTask(Context ctx) {
            mContext = ctx;
        }

        @Override
        protected String doInBackground(URL... params) {
            StringBuilder sb = new StringBuilder();
            try {
                URLConnection connection = params[0].openConnection();
                // 打開connection連接對應的輸入流,並將它包裝成BufferedReader
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        connection.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                    hasRead++;
                    publishProgress(hasRead);
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            // 返回HTML頁面的內容
            show.setText(result);
            pdialog.dismiss();
        }

        @Override
        protected void onPreExecute() {
            pdialog = new ProgressDialog(mContext);
            // 設置對話框的標題
            pdialog.setTitle("任務正在執行中");
            // 設置對話框 顯示的內容
            pdialog.setMessage("任務正在執行中,敬請等待...");
            // 設置對話框不能用“取消”按鈕關閉
            pdialog.setCancelable(false);
            // 設置該進度條的最大進度值
            pdialog.setMax(202);
            // 設置對話框的進度條風格
            pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            // 設置對話框的進度條是否顯示進度
            pdialog.setIndeterminate(false);
            pdialog.show();
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // 更新進度
            show.setText("已經讀取了【" + values[0] + "】行!");
            pdialog.setProgress(values[0]);
        }
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章