FC2ブログ
HOME   »  スポンサー広告  »  スポンサーサイト   »  Android  »  [Android]マルチスレッドでBluetoothAdapterクラスを扱う場合の注意点

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Android]マルチスレッドでBluetoothAdapterクラスを扱う場合の注意点

BluetoothAdapterクラスのインスタンスは、コンストラクタではなくBluetoothAdapterクラスのgetDefaultAdapterメソッドを使用して取得する。
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
下記では、BluetoothAdapterのインスタンスを問題なく取得でき、Toastによる"Completed"メッセージが表示される。
public class MainActivity extends Activity {
    private BluetoothAdapter bluetoothAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter != null) {
            Toast.makeText(this, "Completed", Toast.LENGTH_SHORT).show();
        }
    }
}
しかし下記では、getDefaultAdapterメソッド実行時にRuntimeException("Can't create handler inside thread that has not called Looper.prepare()")がスローされてしまう。
public class MainActivity extends Activity {
    private BluetoothAdapter bluetoothAdapter;
    private Handler handler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        handler = new Handler();
        new Thread() {
            @Override
            public void run() {
                bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                if (bluetoothAdapter != null) {
                    handler.post(new Runnable() {
                        public void run() {
                            Toast.makeText(MainActivity.this, "Completed", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }.start();
    }
}
これは、getDefaultAdapterメソッドあるいはそこから呼ばれる別のメソッドの中でHandlerクラスあるいはそのサブクラスのコンストラクタを実行しているからである。

Handlerクラス及びそのサブクラスはメッセージの投げ先として、コンストラクタの引数あるいは内部処理にてLooperクラスのインスタンスを取得して保持しており、このLooperクラスのインスタンスはスレッドと1対1で関連付けられている(1つのスレッドには1つのLooperクラスのインスタンスのみが存在し得る)。
上記の失敗する場合では、getDefaultAdapterメソッドがメインスレッドとは別のスレッドで実行されており、このスレッドには関連付けられたLooperクラスのインスタンスが存在しない為、結果としてHandlerクラスあるいはそのサブクラスのコンストラクタにてRuntimeExceptionがスローされることになる(メインスレッド(UIスレッド)には裏で自動的にLooperクラスのインスタンスが関連付けられている為、特に意識する必要はないが、自前のスレッドではLooperクラスのprepareメソッドを実行して明示的に関連付ける必要がある)。

マルチスレッドでBluetoothAdapterクラスを扱う場合は注意が必要である。


関連記事
Comment
Trackback
Trackback URL
Comment Form
管理者にだけ表示を許可する
プロフィール

まさお

Author:まさお
プログラミングは趣味レベルなので、お手柔らかに。

ブログランキング
ブログランキング参加中。是非クリックお願いします。


にほんブログ村 IT技術ブログ Androidアプリ開発へ

人気ブログランキングへ

ブログランキング



ブログ王

ブログランキング【ブログの惑星】

プログラム人気ブログランキング
最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。