zoukankan      html  css  js  c++  java
  • Android之Handler用法总结[一]

    以谷歌自带的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 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);
      }
    });

    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之间的通信。

  • 相关阅读:
    安装wampserver2时出现的问题
    微信相关信息
    YII CDbCriteria总结
    discuz@功能的代码
    音乐搜索并生成播放功能
    php生成json和js解析json
    Discuz!提取文章标签
    ⑦ vue项目结构study
    ⑤ elementui 使用字符填充table空白表格项
    ④ keep-alive缓存组件,操作之后需要重新获取数据--activated
  • 原文地址:https://www.cnblogs.com/jayhust/p/4171636.html
Copyright © 2011-2022 走看看