这个错误翻译的意思是:不能在没有Looper.prepare的线程里面创建handler。

起初我很疑惑,我根本没有用到工作线程,也没有创建handler。报错的代码如下:

    // Device scan callback.    private BluetoothAdapter.LeScanCallback mLeScanCallback =            new BluetoothAdapter.LeScanCallback() {                @Override                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {                    final iBeaconClass.iBeacon ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord);                    if (mFilter.isDevice(ibeacon)) {                        scanLeDevice(false);//停止扫描                        T.showShort(getActivity(), getString(R.string.sign_in_success));                        AppSettings.setPrefString(getActivity(), Config.ISSIGNIN, mCurrentDate);                        setButtonState();//改变按钮的状态                        DialogUtils.proGone();                       // mControl.closeBlue();//关闭蓝牙                      }                }            };

百度了下,网上的做法是如下:

Looper.prepare();BluetoothAdapter.getDefaultAdapter();

在获取BluetoothAdapter的之前,加上Looper.prepare();,然并卵。问了很多人,都说不知,这时候这能自力更生了。最后终于被我找到解决办法。

思路:我查看了SDK的源码,发现原来我再调用Toast的时候,创建了handler,源码如下,


当我查看TN这个类的时候,就发现了问题的所在

类 TN 是一个aidl的.Stub的子类,而Toast的显示和隐藏都是通过此类进行通信的,而里面使用handler,具体原理我就不深究下去了。我于是猜想 new BluetoothAdapter.LeScanCallback()的onLeScan可能并没有运行在主线程,于是我调用了runOnUiThread()方法,结果果然解决了。修改后代码如下:

 // Device scan callback.    private BluetoothAdapter.LeScanCallback mLeScanCallback =            new BluetoothAdapter.LeScanCallback() {                @Override                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {                    final iBeaconClass.iBeacon ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord);                    if (mFilter.isDevice(ibeacon)) {                        scanLeDevice(false);//停止扫描                        getActivity().runOnUiThread(new Runnable() {//UI线程的控件改变状态,需要调用此方法,不然可能会无效                            @Override                            public void run() {                                T.showShort(getActivity(), getString(R.string.sign_in_success));                                AppSettings.setPrefString(getActivity(), Config.ISSIGNIN, mCurrentDate);                                setButtonState();                                DialogUtils.proGone();                                // mControl.closeBlue();//关闭蓝牙                            }                        });                    }                }            };

到此,问题已解决,为了让其他同道碰到此问题,而减少寻找bug的时间,特写此博客,告知!

更多相关文章

  1. 习题二
  2. Android中查看CPU和内存
  3. Android(安卓)Suspend/resume 过程分析.
  4. Android之对话框Dialog(二)
  5. Android底层开发Led控制实验
  6. Android中TextView的某一关键字高亮显示
  7. 关于Android加载图片时的OOM的一些解决方法和优化
  8. 【Android】Android中使用JNI调用底层C++代码
  9. Android--多线程之Handler

随机推荐

  1. frame动画
  2. Android之Gallery和ImageSwitcher结合的
  3. android――activity添加退出动画
  4. Android 显示当前服务的代码片段
  5. Android(安卓)Studio 提示错误 default a
  6. 设置里首选网络类型由3G改成4G
  7. Android 指南针程序
  8. android 关于localhost和访问本机服务的
  9. android 交叉编译工具的认识
  10. android日历和时间选择器 普通选择和dial