2016-06-28 6 views
1

자바 컴파일러 동작과 안드로이드의 다른 API에 관한 질문이 있습니다.자바에서 초기화 및 용도가없는 선언 필드

블루투스 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의 초기화는 문이면 안에 있습니다. 그래서 제 질문은 :

내가 더 초기화 및 _scanCallback의 용도가없는 경우 제거됩니다 API를 < 21 컴파일러 장치에 선언 private MyScanCallback _scanCallback; 어떤 문제가 있습니까?

감사합니다.

UDT

아, 난 MyScanCallback 21 API 레벨에서 ScanCallback 느릅 나무입니다 상속 말하지 않았다 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을 사용한다고 언급했듯이 확실히 이전 버전에서 사용하는 것이 문제가됩니다.

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이 21 API 레벨의 'public class EegScanCallback extends ScanCallback'의 ScanCallback을 상속 받았다고 말하지 않았습니다. 그래서 어떤 문제가되지 않을까요? 이 클래스의 필드 선언 –

+0

위대한! 공유 주셔서 감사합니다 ... 내 대답을 같은 업데이 트되었습니다. –

+0

답장을 보내 주셔서 감사합니다. 위대한 아이디어 –