2013-05-25 4 views
1

Я строй приложения-чата для 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; 
    } 
} 
}; 

это дает мне следующее предупреждение: этот класс обработчика должен быть статическим или утечка может произойти

Но когда я меняю его на статичный, он заполняется ошибками.

Вот полный код моей основной деятельности (не ставил весь импорт и прочее здесь, хотя, чтобы избежать слишком долго):

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); 
} 
} 

Это делает его падение. Кто-нибудь, кто может мне помочь? Любая помощь приветствуется. Дайте мне знать, если я что-то добавлю к этому вопросу,

Спасибо за ваше время.

+0

Вы должны отступа свой код, чтобы сделать его проще для других, чтобы читать (в противном случае вы можете не получить столько ответов) , Также подумайте об уменьшении количества кода, который вы публикуете здесь, в StackOverflow (это также увеличит количество ответов, которое вы получите). –

+0

Спасибо за совет. Что такое отступ? – Marshall

+0

http://en.wikipedia.org/wiki/Indent_style –

ответ

1

Предупреждение, которое оно дает, на самом деле правильное. Способ, которым вы объявили класс Handler, не рекомендуется. Ваша текущая реализация фактически создает внутренний класс (обработчик)

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

Handlers and memory leaks in Android

Смежные вопросы