Android之Handler用法總結[一]

來源:互聯網
上載者:User

標籤:android   style   blog   ar   io   color   os   sp   for   

以Google內建的Bluetooth Chat舉例說明,例子中有三個源檔案,分別為:BluetoothChat.java, DeviceListActivity.java, BluetoothChatService.java。

其中BluetoothChat.java是主UI的Activity,DeviceListActivity.java是配對裝置列表選擇UI的Activity,BluetoothChatService.java是功能類內含多個

線程的定義。

1. 主UI中定義Handler成員變數mHandler:

  // The Handler that gets information back from the BluetoothChatService  private final Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {            case MESSAGE_STATE_CHANGE:                if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);                switch (msg.arg1) {                case BluetoothChatService.STATE_CONNECTED:                    setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));                    mConversationArrayAdapter.clear();                    break;                case BluetoothChatService.STATE_CONNECTING:                    setStatus(R.string.title_connecting);                    break;                case BluetoothChatService.STATE_LISTEN:                case BluetoothChatService.STATE_NONE:                    setStatus(R.string.title_not_connected);                    break;                }                break;            case MESSAGE_WRITE:                byte[] writeBuf = (byte[]) msg.obj;                // construct a string from the buffer                String writeMessage = new String(writeBuf);                mConversationArrayAdapter.add("Me:  " + writeMessage);                break;            case MESSAGE_READ:                byte[] readBuf = (byte[]) msg.obj;                // construct a string from the valid bytes in the buffer                String readMessage = new String(readBuf, 0, msg.arg1);                mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);                break;            case MESSAGE_DEVICE_NAME:                // save the connected device‘s name                mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);                Toast.makeText(getApplicationContext(), "Connected to "                               + mConnectedDeviceName, Toast.LENGTH_SHORT).show();                break;            case MESSAGE_TOAST:                Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),                               Toast.LENGTH_SHORT).show();                break;            }        }    };

2. 主UI中初始化BluetoothChatService的執行個體,並在初始化時將mHandler作參數傳遞給執行個體:

  private void setupChat() {        Log.d(TAG, "setupChat()");        // Initialize the array adapter for the conversation thread        mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);        mConversationView = (ListView) findViewById(R.id.in);        mConversationView.setAdapter(mConversationArrayAdapter);        // Initialize the compose field with a listener for the return key        mOutEditText = (EditText) findViewById(R.id.edit_text_out);        mOutEditText.setOnEditorActionListener(mWriteListener);        // Initialize the send button with a listener that for click events        mSendButton = (Button) findViewById(R.id.button_send);        mSendButton.setOnClickListener(new OnClickListener() {            public void onClick(View v) {                // Send a message using content of the edit text widget                TextView view = (TextView) findViewById(R.id.edit_text_out);                String message = view.getText().toString();                sendMessage(message);            }        });        // Initialize the BluetoothChatService to perform bluetooth connections        mChatService = new BluetoothChatService(this, mHandler);        // Initialize the buffer for outgoing messages        mOutStringBuffer = new StringBuffer("");    }

3. 主UI中定義事件響應函數(發送按鈕),其中調用sendMessage函數:

// Initialize the send button with a listener that for click eventsmSendButton = (Button) findViewById(R.id.button_send);mSendButton.setOnClickListener(new OnClickListener() {  public void onClick(View v) {    // Send a message using content of the edit text widget    TextView view = (TextView) findViewById(R.id.edit_text_out);    String message = view.getText().toString();    sendMessage(message);  }});

4. sendMessage函數中,調用功能類BluetoothChatService.java的子函數:

  /**     * Sends a message.     * @param message  A string of text to send.     */    private void sendMessage(String message) {        // Check that we‘re actually connected before trying anything        if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {            Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();            return;        }        // Check that there‘s actually something to send        if (message.length() > 0) {            // Get the message bytes and tell the BluetoothChatService to write            byte[] send = message.getBytes();            mChatService.write(send);            // Reset out string buffer to zero and clear the edit text field            mOutStringBuffer.setLength(0);            mOutEditText.setText(mOutStringBuffer);        }    }

注意這裡的mChatSercice.write(send)函數,出於安全執行緒的考慮,在BluetoothChatService.java中是這麼定義的:

  /**     * Write to the ConnectedThread in an unsynchronized manner     * @param out The bytes to write     * @see ConnectedThread#write(byte[])     */    public void write(byte[] out) {        // Create temporary object        ConnectedThread r;        // Synchronize a copy of the ConnectedThread        synchronized (this) {            if (mState != STATE_CONNECTED) return;            r = mConnectedThread;        }        // Perform the write unsynchronized        r.write(out);    }

這裡定義了一個臨時線程類ConnectedThread r,而這個線程類的定義如下:

    /**     * This thread runs during a connection with a remote device.     * It handles all incoming and outgoing transmissions.     */    private class ConnectedThread extends Thread {        private final BluetoothSocket mmSocket;        private final InputStream mmInStream;        private final OutputStream mmOutStream;        public ConnectedThread(BluetoothSocket socket, String socketType) {            Log.d(TAG, "create ConnectedThread: " + socketType);            mmSocket = socket;            InputStream tmpIn = null;            OutputStream tmpOut = null;            // Get the BluetoothSocket input and output streams            try {                tmpIn = socket.getInputStream();                tmpOut = socket.getOutputStream();            } catch (IOException e) {                Log.e(TAG, "temp sockets not created", e);            }            mmInStream = tmpIn;            mmOutStream = tmpOut;        }        public void run() {            Log.i(TAG, "BEGIN mConnectedThread");            byte[] buffer = new byte[1024];            int bytes;            // Keep listening to the InputStream while connected            while (true) {                try {                    // Read from the InputStream                    bytes = mmInStream.read(buffer);                    // Send the obtained bytes to the UI Activity                    mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)                            .sendToTarget();                } catch (IOException e) {                    Log.e(TAG, "disconnected", e);                    connectionLost();                    // Start the service over to restart listening mode                    BluetoothChatService.this.start();                    break;                }            }        }        /**         * Write to the connected OutStream.         * @param buffer  The bytes to write         */        public void write(byte[] buffer) {            try {                mmOutStream.write(buffer);                // Share the sent message back to the UI Activity                mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();            } catch (IOException e) {                Log.e(TAG, "Exception during write", e);            }        }        public void cancel() {            try {                mmSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of connect socket failed", e);            }        }    }

 從write()函數的定義中可以看到,mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer) .sendToTarget()實現了線程和主UI之間的通訊。

Android之Handler用法總結[一]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.