이전 버전과 호환되는 Android 코드 작성
최신 API 레벨 16에서만 사용할 수 있는 일부 기능과 클래스를 사용하는 앱을 작성 중이지만 API 레벨 15의 기기에서 오류 없이 실행되기를 원합니다.
몇 가지 예를 사용하겠습니다. 새 클래스: Android.widget.Advanceable
및 새/이름이 변경된 메서드 View.setBackground()
:
다음과 같이 할 수 있습니다.
Advanceable myAdvanceable = ...;
if (android.os.Build.VERSION.SDK_INT >= 16)
{
myView.setBackground(...);
myAdvanceable.advance();
}
else
{
myView.setBackgroundDrawable(...); // The old function name.
// Don't bother advancing advanceables.
}
그리고 minSdk를 15로 설정하고 빌드 대상을 16으로 설정하면(즉, 프로젝트 속성->Android에서) 실제로 오류 없이 컴파일됩니다. 적어도 일부 시간. Eclipse는 오류에 대해 약간 확률론적이며 "setBackground()는 API 레벨 >= 16에서만 사용할 수 있습니다." 또는 이와 유사하지만 프로젝트를 정리하기만 하면 해당 오류가 마술처럼 사라집니다.
그래서 내 질문은 내가 이것을 할 수 있습니까? API 레벨 15 기기에서 실행하면 코드가 충돌하지 않습니까? 실제로 16 코드에 도달하면 충돌이 발생합니까? Eclipse가 빌드를 막지 못하는 이유는 무엇입니까?
편집 1
답변 감사합니다. 질문은 다음과 같습니다. 새 API 사용에 대해 Lint가 경고하지 않는 이유는 무엇입니까?
내 매니페스트에 이것을 가지고 있으며 API 레벨 16 기능을 사용하고 있지만 여전히 경고하지 않습니다.
<uses-sdk android:minSdkVersion="15"
android:targetSdkVersion="16"/>
또한 전체 클래스가 언제 API 수준(예: Advanceable
. 특히 멤버 변수로 사용하는 경우.
편집 2
대답은 "Eclipse는 지옥처럼 버그가 있습니다"로 밝혀졌지만 Nico의 대답도 매우 도움이되었습니다.
인라인 Api 오류는 ADT의 새로운 기능입니다. Eclipse는 Lint를 실행하여 코드를 분석하고 해당 오류/경고를 인라인으로 표시합니다. 최적화 또는 모범 사례에 대한 경고나 힌트가 있는 경우 xml 레이아웃에도 동일하게 적용됩니다. 주석을 사용하여 클래스 또는 특정 메서드에서 이러한 오류를 억제할 수 있습니다.
@TargetApi(16)
@SuppressLint("NewApi")
여기에 넣은 샘플 코드에 문제가 있습니다. API 레벨 검사 옆에 API < 16에서 작동하지 않는 코드에 Advanceable 인스턴스가 있으므로 API 레벨 검사는 새 메소드를 호출할 때만 유용하지만 할 수 없습니다. IF 블록 외부의 새 API 클래스를 참조하십시오.
내가 받아들일 수 있는 한 가지 접근 방식은 추상 클래스와 두 가지 구현을 만든 다음 올바른 구현을 인스턴스화하기 위해 정적 메서드와 함께 팩토리 클래스를 사용할 수 있는 것입니다.
예를 들어 내부적으로 몇 가지 새로운 API 클래스와 메서드를 사용하는 보기를 만들려면 다음이 필요합니다.
1 - 추상 클래스 생성:
public abstract class CustomView {
public abstract void doSomething();
}
- 모든 API와 호환되는 공통 구현
- 구현을 분할하기 위해 여기에 추상 메소드를 정의하십시오.
2 - 레거시 구현
public class CustomLegacyView extends CustomView {
public void doSomething(){
//implement api < 16
}
}
- API < 16에 대한 추상 메소드 구현
3 - API 16 구현
@TargetApi(16)
public class CustomL16View extends CustomView {
Advanceable myAdvanceable;
public void doSomething(){
//implement api >= 16
}
}
- @TargetApi(16) 주석 사용
- API >= 16에 대한 추상 메서드 구현
- 여기에서 레벨 16 클래스를 참조할 수 있습니다(CustomView에서는 제외).
4 - 공장 클래스
public class ViewFactory {
public static CustomView getCustomView(Context context) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new CustomL16View(context);
}else{
return new CustomLegacyView(context);
}
}
}
It is a common practice to use a newer build target and guarantee newer API will be called in the right circumstances. Google even added @TargetApi()
annotation since ADT 17 to specify local overrides for conditionally loaded code.
See Lint API check for more details.
1. You have Target Api
and Minimum SDK
attributes to define what kind of device are you targeting and which will be the least Api version on which it will run.
2. Target Api
will be the one on which the App runs with Full features, whereas Minimum SDK
will make the App run on it with some Compromises as there can be chances that the lower API version dont have the features which are in its higher versions.
ReferenceURL : https://stackoverflow.com/questions/11592820/writing-backwards-compatible-android-code
'IT이야기' 카테고리의 다른 글
Symfony 2 : 다중 및 동적 데이터베이스 연결 (0) | 2021.10.21 |
---|---|
git의 기록에서 제거하지 않고 분기를 닫는 방법 (0) | 2021.10.21 |
Simplemembership을 사용하는 새로운 MVC 4 인터넷 템플릿의 역할 기반 인증 (0) | 2021.10.20 |
Node.js 코드의 아무 곳에서나 MongoDB 연결을 닫지 않는 것이 권장되는 이유 (0) | 2021.10.20 |
여러 페이지에서 탐색 모음을 재사용하려면 (0) | 2021.10.18 |