これは以前に何度も議論されてきましたが、それでも私にとっては本当に苦痛です。
問題: TextView のテキストを更新しようとすると、アプリがクラッシュする
コンテキスト:マルチスレッドでBluetoothアプリを使用しています。「リスニング」スレッド (ConnectedThread) は、新しいメッセージが取得されるたびに Handler を送信します。このハンドラーは、TextView が初期化されるメイン アクティビティで解決されます。
これまでに試したこと/確認したこと:
- 別のアクティビティ/スレッドから TextView を更新していないと思います
- setContentView(R.layout.main); の後に TextView が初期化されます。(まあ、別の投稿で、これが問題を引き起こしていました)
コード: (要するに)
主な活動
public class BluetoothActivity extends Activity {
private TextView mDisplay;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
.....
..
}
private void setupApp() {
// Initialize the BluetoothService to perform bluetooth connections
// This is where the Handler is passed to "ConnectedThread" (it is part of
mService)
mService = new BluetoothService(this, mHandler);
}
// The Handler that gets information back from the BluetoothService
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
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);
if(D) Log.d(TAG, "Received: " + readMessage);
mDisplay.setText(readMessage); <----- THIS IS THE ISSUE
break;
.......
....
}
}
};
接続されたスレッド
private class ConnectedThread extends Thread {
......
public void run() {
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(BluetoothActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch ...
}
}
}
主に、これは受信メッセージを表示するための機能でした
Toast.makeText(getApplicationContext(), "Received: " + readMessage,
Toast.LENGTH_SHORT).show();