2015-06-02 55 views
2

我程序性的机器人BLE sample.I希望它刚才显示外围巫婆它已经扫描我的名单上view.Why我必须把为什么必须将代码放在“runonuithread”方法中?

mLeScanListAdpter.addDevice(device); 
mLeScanListAdpter.notifyDataSetChanged(); 

runOnUiThread()方法?

如果我不使用这种方法,当我的程序发现一个设备时,列表视图将不会显示设备信息,它会在我触摸手机屏幕几秒钟后显示它。 我认为,onLeScan()方法上主要thread.So运行,

mLeScanListAdpter.addDevice(device); 
mLeScanListAdpter.notifyDataSetChanged(); 

运行在主线程,甚至我不把它放在runOnUiThread()方法。并且,主要thread = UI thread,不是吗?

所以,我认为,它运行在ui Thread上,即使我不把它放在runOnUiThread()的方法中。但实际上,这是行不通的,我必须把它放在runOnUiThread()的方法中。 我很困惑,为什么?

这是我的代码。

public class MainActivity extends ListActivity { 

BluetoothManager bluetoothManager; 
BluetoothAdapter bluetoothAdapter; 
static final int REQUEST_ENABLE_BT = 0; 
private Handler mHandler = new Handler(); 
LeScanListAdpter mLeScanListAdpter = new LeScanListAdpter(); 

BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { 

    @Override 
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { 

     /*------------!!!!!!!!Pay attention!!!!!!!--------------- 
      ------------There is the question--------------------*/ 
     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       mLeScanListAdpter.addDevice(device); 
       mLeScanListAdpter.notifyDataSetChanged(); 

       Log.w("scan", 
         "name:" + device.getName() + " address:" 
           + device.getAddress()); 
      } 
     }); 
    } 


}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setListAdapter(mLeScanListAdpter); 

    // 1.获取manager 
    bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); 
    // 2.获取adapter 
    bluetoothAdapter = bluetoothManager.getAdapter(); 
    // 3.开启蓝牙 
    /* 
    * 调用isEnabled())去检测蓝牙当前是否开启。 如果该方法返回false,蓝牙被禁用。 
    * 如果没有开启,将显示错误提示用户去设置开启蓝牙。 
    */ 
    if (!bluetoothAdapter.isEnabled()) { 
     Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(intent, REQUEST_ENABLE_BT); 
    } 
    // 4.扫描ble设备 
    LeScan(); 

} 

private void LeScan() { 

    mHandler.postDelayed(new Runnable() { 

     @Override 
     public void run() { 
      bluetoothAdapter.stopLeScan(mLeScanCallback); 
     } 
    }, 10000); 

    bluetoothAdapter.startLeScan(mLeScanCallback); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

private class LeScanListAdpter extends BaseAdapter { 

    private ArrayList<BluetoothDevice> allDevices; 

    public LeScanListAdpter() { 
     super(); 
     allDevices = new ArrayList<BluetoothDevice>(); 

    } 

    @Override 
    public int getCount() { 

     return allDevices.size(); 
    } 

    public void addDevice(BluetoothDevice d) { 
     if(allDevices.contains(d)){ 
      return; 
     } 

     allDevices.add(d); 
    } 

    @Override 
    public Object getItem(int position) { 

     return allDevices.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     BluetoothDevice d = allDevices.get(position); 
     // 如果view为null 
     if (convertView == null) { 
      convertView = MainActivity.this.getLayoutInflater().inflate(
        R.layout.activity_main, null); 

     } 
     if (d.getName() == null) { 
      ((TextView) convertView.findViewById(R.id.name_text_view)) 
        .setText("unknown"); 
      ((TextView) convertView 
        .findViewById(R.id.device_address_text_view)).setText(d 
        .getAddress()); 
     } else { 
      ((TextView) convertView.findViewById(R.id.name_text_view)) 
        .setText(d.getName()); 
      ((TextView) convertView 
        .findViewById(R.id.device_address_text_view)).setText(d 
        .getAddress()); 
     } 
     return convertView; 
    } 

    } 
} 

回答

0

UI可以在主线程可以改变,不是线程只有“主线”

也许onLeScan()方法的线程上运行,而不是主线程,

ü可以检查...

if(Looper.myLooper() == Looper.getMainLooper()) { 
you are on ui thread 
} else { 
you are not on ui thread 
} 
+0

谢谢你!我发现它在另一个线程上运行。 –

相关问题