2016-06-28 38 views
1

我有一個問題涉及到java編譯器的行爲以及android的不同API。在Java中沒有初始化和用法的字段聲明

我有代表藍牙LE連接的類。我在這個類中檢查API的版本,以瞭解哪些方法可以掃描我必須使用的設備。那就是:

public class BleConnector{ 

    private MyScanCallback _scanCallback; 


private LeScanHandle _leScanHndl; 
private BluetoothAdapter _bluetoothAdapter; 

/** 
* Initializes new instance of BLE connector 
*/ 
public BleConnector() 
{ 
    //Creating handle for device scan callback; 
    _leScanHndl = new LeScanHandle(); 

    //Check version of android api 
    //If it is bigger of equal to 21 
    //create scan callback for higher versions 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
    { 
     _scanCallback = new ScanCallback(_leScanHndl); 
    } 
} 


public void startScan(Context context) throws PermissoinException 
{ 
    final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); 
    _bluetoothAdapter = bluetoothManager.getAdapter(); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
    { 
     if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
     { 
      _bluetoothAdapter.getBluetoothLeScanner().startScan(_scanCallback); 
     } 
     else 
     { 
      throw new PermissoinException("Location permission does not allowed"); 
     } 
    } 
    else 
    { 
     _bluetoothAdapter.startLeScan(_leScanHndl); 
    } 
    //TODO notify 
} 

public void stopScan() 
{ 
    if (_bluetoothAdapter != null) 
    { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
     { 
      _bluetoothAdapter.getBluetoothLeScanner().stopScan(_scanCallback); 
     } else 
     { 
      _bluetoothAdapter.stopLeScan(_leScanHndl); 
     } 
    } 

    //TODO notify 
} 

private void connectToDevice(BluetoothDevice device) 
{ 
    //TODO notify 

    //TODO connect gatt 
} 

類MyScanCallback標有@TargetAPI 21,當然我並不想用它來工作,如果我的設備的版本低於21

正如你可以看到所有的用法並且初始化_scanCallback都在之內,如果是聲明。所以我的問題是:

我將有一設備帶有聲明private MyScanCallback _scanCallback;任何麻煩與API < 21或編譯器,如果沒有初始化和_scanCallback慣例將刪除呢?

謝謝!

UDT

哦,我並沒有說MyScanCallback繼承ScanCallback至極從21 API級別public class MyScanCallback extends ScanCallback

回答

2

@TargetApi 21只是防止任何編譯錯誤所用的任何新的API。 Byt實際上避免了代碼被執行,它必須被包裹在構建版本檢查中,就像你在幾個地方做過的一樣。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
{ 
} 

所以在這種情況下,絕對是一個MyScanCallback的變量將被創建,但它不會在設備與API < 21實例化爲您在構造函數中裹住版本檢查。

正如您所提到的,它使用API​​ 21中引入的ScanCallback,那麼在舊版本中使用ScanCallback肯定會有問題。

爲了擺脫這一點,我建議如下創建一個抽象類:

public abstract class BleConnector{ 

public abstract void startScan(Context context); 

} 

,然後創建兩個類

public class BleConnectOldApi extends BleConnector{ 
public void startScan(Context context) throws PermissoinException { 
//Your code here 
} 
} 

@TargetApi(21) 
public class BleConnect21Api extends BleConnector{ 

private MyScanCallback _scanCallback; 

public void startScan(Context context) throws PermissoinException { 
//Your code here 
} 
} 

最後有工廠分類

public class BleConnectorFactory{ 

    public static BleConnector getBleConnector() { 

     if (android.os.Build.VERSION.SDK_INT >= 21) { 
      return new BleConnect21Api(); 
     }else{ 
      return new BleConnectOldApi(); 
     } 

    } 
} 

通過這種方式,您可以防止使用舊API版本中不存在的類的不需要的錯誤。

希望能幫助你。

+0

噢,我沒有說MyScanCallback繼承了ScanCallback,它來自21 API級別的公共類EegScanCallback擴展了ScanCallback。那它不會有什麼麻煩嗎?這個類的領域的宣言 –

+0

太棒了!感謝分享...更新我的答案相同。 –

+0

非常感謝你的回答!好主意 –