java - 处理程序类应该是静态的吗?

标签 java android error-handling handler

我正在为 android 和以下部分(第二行)构建一个聊天应用程序:

// 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:
        switch (msg.arg1) {
        case BluetoothChatService.STATE_CONNECTED:
            //setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
            otherDeviceName.setText(mConnectedDeviceName.toString());
            mConversationArrayAdapter.clear();
            break;
        case BluetoothChatService.STATE_CONNECTING:
            //setStatus(R.string.title_connecting);
            break;
        case BluetoothChatService.STATE_LISTEN:
        case BluetoothChatService.STATE_NONE:
            otherDeviceName.setText(R.string.friendo);
            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;
    }
}
};

它给了我以下警告: 此处理程序类应该是静态的,否则可能会发生泄漏

但是当我将其更改为静态时,它会充满错误。

这是我的主要 Activity 的完整代码(虽然没有把所有的导入和东西放在这里,以避免太长):

public class MainActivity extends Activity {

/* Message types sent from the BluetoothChatService Handler */
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;

/* Name of the other device received from the BluetoothChatService Handler */
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";

/* Intent request codes. For show and connect */
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_ENABLE_BT = 3;

/*Initializing part*/
 TextView chatHistory;
 TextView otherDeviceName;
 BluetoothAdapter mBluetoothAdapter = null;
 EditText myTextbox;
 private String mConnectedDeviceName = null; // Name of the connected device
 private ArrayAdapter<String> mConversationArrayAdapter; // Array adapter for the conversation thread
 private StringBuffer mOutStringBuffer;   // String buffer for outgoing messages
 private BluetoothChatService mChatService = null; // Member object for the chat services

/*On Create*/ 
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    setContentView(R.layout.activity_main);

    /*Now we connect the names to the actual objects in the activity*/
    Button connectButton = (Button)findViewById(R.id.button2);
    Button showButton = (Button)findViewById(R.id.button3);
    otherDeviceName = (TextView)findViewById(R.id.textView1);
    chatHistory = (TextView)findViewById(R.id.textView2);
    myTextbox = (EditText)findViewById(R.id.editText1);
    myTextbox.setMovementMethod(new ScrollingMovementMethod());

   /*First we make sure that the user has bluetooth (otherwise this App has no use)
    This was previously located in findBT(), but it seemed unnecesary to have it that late*/
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(mBluetoothAdapter == null) //if there is no bluetooth
    {
        Toast.makeText(this, "This device doesn't have Bluetooth. Adquire new device", Toast.LENGTH_LONG).show(); 
        //Toast is like a pop-up that displays the message. Changed to this so it doesn't display it in the chat history
        finish(); //close activity
        return;
    } 

    chatHistory.setText("Welcome " + mBluetoothAdapter.getName() + "!");

     /*For personal reasons the user might not want to activate the bluetooth until later (for example if the other user is still installing the app).
     Therefore turning on bluetooth won't be requested until he chooses to connect or show */


  /*connect Button: Send you to the connection activity */
    connectButton.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View view)
        {
            Intent myIntent = new Intent(view.getContext(), ConnectionActivity.class);
            startActivityForResult(myIntent, REQUEST_CONNECT_DEVICE_SECURE);
            // Launch the DeviceListActivity to see devices and do scan               
        }
    });

    /*show Button: has to make you visible. No need for the turn on bluetooth, because it does it automatically together with the discovery */
    showButton.setOnClickListener(new View.OnClickListener()
    {
                @Override
                public void onClick(View v) {
                    if (mBluetoothAdapter.getScanMode() != //getscanmode finds out if other can discover us
                            BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { //makes sure other devices can find us AND connect to us
                            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); //asks for permission to (turn on bluetooth) and make me visible
                            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); //makes me discoverable for 300 seconds
                            startActivity(discoverableIntent); 

                    }
                }
            });
}

/*ON START, RESUME, PAUSE, STOP AND DESTROY*/
@Override
public void onStart() {
super.onStart();
if (mChatService == null) setupChat(); //setupChat again if not done yet.
}

@Override
public synchronized void onResume() {
super.onResume();
if (mChatService != null) {
    // Only if the state is STATE_NONE, do we know that we haven't started already
    if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
      // Start the Bluetooth chat services
      mChatService.start();
    }
}
}
@Override
public synchronized void onPause() {
super.onPause();
}

@Override
public void onStop() {
super.onStop();
}

@Override
public void onDestroy() {
super.onDestroy();
if (mChatService != null) mChatService.stop();
}

/* The send button */
private void setupChat() {
/*Step 1: The listener for the send button */
Button sendButton = (Button)findViewById(R.id.button1);
sendButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        String message = chatHistory.getText().toString(); //save the written thing in message
        sendMessage(message); //run the sendMessage


    }
});

/* Step 2: Initialize the BluetoothChatService to perform bluetooth connections*/
mChatService = new BluetoothChatService(this, mHandler);

/* Step 3: Initialize the buffer for outgoing messages */
mOutStringBuffer = new StringBuffer("");
}

/* Send message  */
private void sendMessage(String message) {
/* Check that we're actually connected before trying anything, so you can't send while not connected */
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);
    myTextbox.setText(mOutStringBuffer);
}
}

// 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:
        switch (msg.arg1) {
        case BluetoothChatService.STATE_CONNECTED:
            //setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
            otherDeviceName.setText(mConnectedDeviceName.toString());
            mConversationArrayAdapter.clear();
            break;
        case BluetoothChatService.STATE_CONNECTING:
            //setStatus(R.string.title_connecting);
            break;
        case BluetoothChatService.STATE_LISTEN:
        case BluetoothChatService.STATE_NONE:
            otherDeviceName.setText(R.string.friendo);
            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;
    }
}
};

public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
    // When DeviceListActivity returns with a device to connect
    if (resultCode == Activity.RESULT_OK) {
        connectDevice(data, true);
    }
    break;
case REQUEST_ENABLE_BT:
    // When the request to enable Bluetooth returns
    if (resultCode == Activity.RESULT_OK) {
        // Bluetooth is now enabled, so set up a chat session
        setupChat();
    } else {
        // User did not enable Bluetooth or an error occurred
        Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
        finish();
    }
}
}

private void connectDevice(Intent data, boolean secure) {
// Get the device MAC address
String address = data.getExtras()
    .getString(ConnectionActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device, secure);
}
}

这会使它崩溃。 任何人都可以帮助我吗? 任何帮助表示赞赏。如果我应该在这个问题上添加一些内容,请告诉我,

感谢您的宝贵时间。

最佳答案

它给出的警告实际上是正确的。不推荐您声明 Handler 类的方式。您当前的实现实际上创建了一个内部类(处理程序)

引用: This Handler class should be static or leaks might occur: IncomingHandler

Handlers and memory leaks in Android

关于java - 处理程序类应该是静态的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16749378/

相关文章:

java - 两个方法同时使用@Asynchronous注解

安卓网页 View

vb.net - 防止VB.Net中的HTMLAgilitypack错误

c++ - 程序是否应该检查 "shouldn' t"但可以失败的 WinAPI 函数的失败?

java - Hibernate-Search flushToIndexes 导致 java.lang.OutOfMemoryError(堆空间)

java - 处理多模块 Maven 项目的依赖关系

java - 如何反序列化这个动态值 JSON?

android - 找不到类 'android.graphics.drawable.RippleDrawable

android - 如何在 android 中禁用 GestureListener?

php - PHP中发生错误时如何获取所有变量