當一般情況我們需要用高版本API 運行在 低版本設備上會使用如下判斷
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
}
但是想我們的抽象類我們大多數都是全局定義並且匿名實例化,舉一個簡單常見的例子:
做過低功耗藍牙掃描的人就知道 ScanCallback 抽象類,一般我們都是通過如下方式去調用,實際大概代碼可能如下:
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
public class Test{
private BluetoothLeScanner mBluetoothLeScanner;
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result)
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
};
public Test(Context context){
init(contxt);
}
pulic void init(Context context){
if (mBluetoothManager == null) {
mBluetoothManager =(BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
}
}
public void startScan(){
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
mBluetoothLeScanner.startScan(scanCallback);
}
}
public void stopScan(){
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
mBluetoothLeScanner.stopScan(scanCallback);
}
}
}
可以看到這種情況,我們的 抽象類 ScanCallback 要想全局定義,我們通過google文檔知道,ScanCallback Add API 21 ,那麼當我們將此代碼運行在Android4.4 API 19 的設備上,必定會出現如下錯誤:
java.lang.NoClassDefFoundError
這個時候我們使用如下也是無濟於事:
@TargetApi(21)
@RequiresApi(21)
private ScanCallback scanCallback = new ScanCallback() {
......
}
再次看到錯誤,通過錯誤分析其實只是在Android 4.4 API 19設備上 ScanCallback 這個類找不到而已,
解決辦法:
通過在我們下載的SDK源碼中找到 ScanCallback 類,然後將它以相同的包名複製到我們的實際項目中,如下圖:
我們再次運行,則不會出現上面的錯誤了,因爲這個時候 它能夠在我們自己的apk 的classes.dex 尋找到該類。
其他的情況以此類推即可。