Khi nói đến việc phát triển ứng dụng cho Android, sự khác biệt giữa phiên bản Min và Target SDK là gì? Eclipse sẽ không cho phép tôi tạo một dự án mới trừ khi các phiên bản Min và Target giống nhau!
Khi nói đến việc phát triển ứng dụng cho Android, sự khác biệt giữa phiên bản Min và Target SDK là gì? Eclipse sẽ không cho phép tôi tạo một dự án mới trừ khi các phiên bản Min và Target giống nhau!
Câu trả lời:
Android: minSdkVersion
Một số nguyên chỉ định Cấp API tối thiểu cần thiết để ứng dụng chạy. Hệ thống Android sẽ ngăn người dùng cài đặt ứng dụng nếu Cấp API của hệ thống thấp hơn giá trị được chỉ định trong thuộc tính này. Bạn nên luôn luôn khai báo thuộc tính này.
android: targetSdkVersion
Một số nguyên chỉ định Cấp API mà ứng dụng đang nhắm mục tiêu.
Với bộ thuộc tính này, ứng dụng nói rằng nó có thể chạy trên các phiên bản cũ hơn (xuống tới minSdkVersion), nhưng đã được kiểm tra rõ ràng để hoạt động với phiên bản được chỉ định ở đây. Chỉ định phiên bản mục tiêu này cho phép nền tảng vô hiệu hóa các cài đặt tương thích không cần thiết cho phiên bản đích (có thể được bật để duy trì khả năng tương thích về phía trước) hoặc bật các tính năng mới hơn không có sẵn cho các ứng dụng cũ. Điều này không có nghĩa là bạn có thể lập trình các tính năng khác nhau cho các phiên bản khác nhau của nền tảng. Nó chỉ thông báo cho nền tảng mà bạn đã kiểm tra so với phiên bản đích và nền tảng không nên thực hiện bất kỳ công việc bổ sung nào để duy trì khả năng tương thích với phiên bản đích.
Để biết thêm thông tin tham khảo URL này:
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
Nhận xét được OP đăng lên câu hỏi (về cơ bản nói rằng TargetSDK không ảnh hưởng đến việc biên dịch ứng dụng) là hoàn toàn sai! Xin lỗi để được cùn.
Nói tóm lại, đây là mục đích để khai báo một TargetSDK khác với minSDK: Điều đó có nghĩa là bạn đang sử dụng các tính năng từ SDK cấp cao hơn mức tối thiểu của bạn, nhưng bạn đã đảm bảo khả năng tương thích ngược . Nói cách khác, hãy tưởng tượng rằng bạn muốn sử dụng một tính năng chỉ mới được giới thiệu gần đây, nhưng điều đó không quan trọng đối với ứng dụng của bạn. Sau đó, bạn sẽ đặt targetSDK thành phiên bản nơi tính năng mới này được giới thiệu và mức tối thiểu ở mức thấp hơn để mọi người vẫn có thể sử dụng ứng dụng của bạn.
Để đưa ra một ví dụ, giả sử bạn đang viết một ứng dụng sử dụng rộng rãi việc phát hiện cử chỉ. Tuy nhiên, mọi lệnh có thể được nhận ra bằng một cử chỉ cũng có thể được thực hiện bằng một nút hoặc từ menu. Trong trường hợp này, cử chỉ là một 'tuyệt vời thêm' nhưng không bắt buộc. Do đó, bạn sẽ đặt sdk mục tiêu thành 7 ("Eclair" khi thư viện GestureDetection được giới thiệu) và tối thiểuSDK lên cấp 3 ("Cupcake") để ngay cả những người có điện thoại thực sự cũ cũng có thể sử dụng ứng dụng của bạn. Tất cả những gì bạn phải làm là đảm bảo rằng ứng dụng của bạn đã kiểm tra phiên bản Android mà nó đang chạy trước khi thử sử dụng thư viện cử chỉ, để tránh cố gắng sử dụng nếu nó không tồn tại. (Phải thừa nhận rằng đây là một ví dụ ngày vì hầu như không ai vẫn có điện thoại v1.5, nhưng đã có lúc duy trì khả năng tương thích với v1.
Để đưa ra một ví dụ khác, bạn có thể sử dụng điều này nếu bạn muốn sử dụng một tính năng từ Gingerbread hoặc Honeycomb. Một số người sẽ sớm nhận được các bản cập nhật, nhưng nhiều người khác, đặc biệt là với phần cứng cũ hơn, có thể vẫn bị mắc kẹt với Eclair cho đến khi họ mua một thiết bị mới. Điều này sẽ cho phép bạn sử dụng một số tính năng mới thú vị, nhưng không loại trừ một phần thị trường có thể của bạn.
Có một bài viết thực sự hay từ blog của nhà phát triển Android về cách sử dụng tính năng này và đặc biệt là cách thiết kế mã "kiểm tra tính năng tồn tại trước khi sử dụng" tôi đã đề cập ở trên.
Gửi cho OP: Tôi đã viết điều này chủ yếu vì lợi ích của bất kỳ ai tình cờ vấp phải câu hỏi này trong tương lai, vì tôi nhận ra câu hỏi của bạn đã được hỏi từ lâu.
Khi bạn đặt targetSdkVersion = "xx", bạn sẽ xác nhận rằng ứng dụng của bạn hoạt động đúng (ví dụ: đã được kiểm tra kỹ lưỡng và thành công) ở cấp độ API xx.
Phiên bản Android chạy ở cấp API trên xx sẽ tự động áp dụng mã tương thích để hỗ trợ bất kỳ tính năng nào bạn có thể dựa vào hoặc có sẵn ở cấp API xx, nhưng hiện đã lỗi thời ở cấp cao hơn của phiên bản Android đó.
Ngược lại, nếu bạn đang sử dụng bất kỳ tính năng nào trở nên lỗi thời ở hoặc trước cấp xx, mã tương thích sẽ không được các phiên bản HĐH tự động áp dụng ở các cấp API cao hơn (không còn bao gồm các tính năng đó) để hỗ trợ các sử dụng đó. Trong tình huống đó, mã riêng của bạn phải có điều khoản trường hợp đặc biệt mà kiểm tra mức độ API và, nếu cấp hệ điều hành được phát hiện là một cao một mà không còn có các tính năng API nhất định, mã của bạn phải sử dụng tính năng thay thế mà là có sẵn tại của hệ điều hành chạy Cấp API.
Nếu không thực hiện được điều này, thì một số tính năng giao diện có thể đơn giản là không xuất hiện mà thường kích hoạt các sự kiện trong mã của bạn và bạn có thể thiếu một tính năng giao diện quan trọng mà người dùng cần để kích hoạt các sự kiện đó và để truy cập chức năng của chúng (như trong ví dụ dưới đây).
Như đã nêu trong các câu trả lời khác, bạn có thể đặt targetSdkVersion cao hơn minSdkVersion nếu bạn muốn sử dụng một số tính năng API ban đầu được xác định ở cấp API cao hơn minSdkVersion của mình và đã thực hiện các bước để đảm bảo rằng mã của bạn có thể phát hiện và xử lý sự vắng mặt của các tính năng đó tại mức thấp hơn mục tiêuSdkVersion.
Để cảnh báo các nhà phát triển kiểm tra cụ thể mức API tối thiểu cần thiết để sử dụng một tính năng, trình biên dịch sẽ đưa ra lỗi (không chỉ là cảnh báo) nếu mã chứa lệnh gọi đến bất kỳ phương thức nào được xác định ở cấp API muộn hơn minSdkVersion, ngay cả khi targetSdkVersion lớn hơn hoặc bằng mức API mà phương thức đó lần đầu tiên được cung cấp. Để loại bỏ lỗi này, chỉ thị của trình biên dịch
@TargetApi(nn)
báo cho trình biên dịch rằng mã trong phạm vi của lệnh đó (sẽ đi trước một phương thức hoặc một lớp) đã được viết để kiểm tra mức API ít nhất là nn trước khi gọi bất kỳ phương thức nào phụ thuộc vào việc có ít nhất mức API đó . Ví dụ: đoạn mã sau định nghĩa một phương thức có thể được gọi từ mã trong một ứng dụng có minSdkVersion dưới 11 và targetSdkVersion từ 11 trở lên:
@TargetApi(11)
public void refreshActionBarIfApi11OrHigher() {
//If the API is 11 or higher, set up the actionBar and display it
if(Build.VERSION.SDK_INT >= 11) {
//ActionBar only exists at API level 11 or higher
ActionBar actionBar = getActionBar();
//This should cause onPrepareOptionsMenu() to be called.
// In versions of the API prior to 11, this only occurred when the user pressed
// the dedicated menu button, but at level 11 and above, the action bar is
// typically displayed continuously and so you will need to call this
// each time the options on your menu change.
invalidateOptionsMenu();
//Show the bar
actionBar.show();
}
}
Bạn cũng có thể muốn khai báo một TargetSdkVersion cao hơn nếu bạn đã thử nghiệm ở cấp độ cao hơn đó và mọi thứ đều hoạt động, ngay cả khi bạn không sử dụng bất kỳ tính năng nào từ cấp API cao hơn minSdkVersion của bạn. Điều này sẽ chỉ để tránh chi phí truy cập mã tương thích dự định thích ứng từ cấp mục tiêu xuống mức tối thiểu, vì bạn đã xác nhận (thông qua thử nghiệm) rằng không yêu cầu thích ứng như vậy.
Một ví dụ về tính năng UI phụ thuộc vào targetSdkVersion được khai báo sẽ là nút menu ba chấm dọc xuất hiện trên thanh trạng thái của các ứng dụng có targetSdkVersion dưới 11, khi các ứng dụng đó chạy dưới API 11 trở lên. Nếu ứng dụng của bạn có targetSdkVersion từ 10 trở xuống, có thể giả định rằng giao diện ứng dụng của bạn phụ thuộc vào sự tồn tại của nút menu chuyên dụng và do đó, nút ba chấm xuất hiện thay thế cho các phiên bản phần cứng và / hoặc trên màn hình chuyên dụng trước đó của nút đó (ví dụ, như đã thấy trong Gingerbread) khi HĐH có mức API cao hơn mà nút menu chuyên dụng trên thiết bị không còn được sử dụng nữa. Tuy nhiên, nếu bạn đặt targetSdkVersion của ứng dụng của bạn thành 11 hoặc cao hơn, có thể giả định rằng bạn đã tận dụng các tính năng được giới thiệu ở cấp đó thay thế nút menu chuyên dụng (e. g., Thanh hành động) hoặc nếu bạn đã tránh được thì cần phải có nút menu hệ thống; do đó, "nút tương thích" của menu ba chấm dọc biến mất. Trong trường hợp đó, nếu người dùng không thể tìm thấy nút menu, cô ấy không thể nhấn nút đó và điều đó có nghĩa là ghi đè onCreateOptionsMothy (menu) của hoạt động của bạn có thể không bao giờ được gọi, lần lượt, có nghĩa là một phần đáng kể chức năng của ứng dụng của bạn có thể bị mất giao diện người dùng. Tất nhiên trừ khi bạn đã triển khai Action Bar hoặc một số phương tiện thay thế khác để người dùng truy cập các tính năng này. Không tìm thấy nút menu, cô ấy không thể nhấn nút và điều đó có nghĩa là ghi đè onCreateOptionsMothy (menu) của hoạt động của bạn có thể không bao giờ được gọi, điều đó, một lần nữa, có nghĩa là một phần quan trọng của chức năng ứng dụng của bạn có thể là tước giao diện người dùng của nó. Tất nhiên trừ khi bạn đã triển khai Action Bar hoặc một số phương tiện thay thế khác để người dùng truy cập các tính năng này. Không tìm thấy nút menu, cô ấy không thể nhấn nút và điều đó có nghĩa là ghi đè onCreateOptionsMothy (menu) của hoạt động của bạn có thể không bao giờ được gọi, điều đó, một lần nữa, có nghĩa là một phần quan trọng của chức năng ứng dụng của bạn có thể là tước giao diện người dùng của nó. Tất nhiên trừ khi bạn đã triển khai Action Bar hoặc một số phương tiện thay thế khác để người dùng truy cập các tính năng này.
Ngược lại, minSdkVersion nêu rõ yêu cầu rằng phiên bản HĐH của thiết bị phải có ít nhất mức API đó để chạy ứng dụng của bạn. Điều này ảnh hưởng đến thiết bị nào có thể xem và tải xuống ứng dụng của bạn khi có trên cửa hàng ứng dụng Google Play (và có thể cả các cửa hàng ứng dụng khác). Đó là một cách để nói rằng ứng dụng của bạn dựa trên các tính năng của HĐH (API hoặc khác) được thiết lập ở cấp đó và không có cách nào có thể chấp nhận để đối phó với sự vắng mặt của các tính năng đó.
Một ví dụ về việc sử dụng minSdkVersion để đảm bảo sự hiện diện của một tính năng không liên quan đến API sẽ đặt minSdkVersion thành 8 để đảm bảo rằng ứng dụng của bạn sẽ chỉ chạy trên phiên bản trình thông dịch Dalvik hỗ trợ JIT (kể từ khi JIT được giới thiệu đến trình thông dịch Android ở API cấp 8). Vì hiệu suất cho trình thông dịch hỗ trợ JIT có thể gấp năm lần so với một tính năng thiếu tính năng đó, nếu ứng dụng của bạn sử dụng nhiều bộ xử lý thì bạn có thể muốn yêu cầu API cấp 8 trở lên để đảm bảo hiệu suất đầy đủ.
Một khái niệm có thể được cung cấp tốt hơn với các ví dụ, luôn luôn . Tôi gặp khó khăn trong việc hiểu khái niệm này cho đến khi tôi đào sâu vào mã nguồn khung Android và thực hiện một số thử nghiệm, ngay cả sau khi đọc tất cả các tài liệu trong các trang web dành cho nhà phát triển Android và các luồng stackoverflow liên quan. Tôi sẽ chia sẻ hai ví dụ giúp tôi rất nhiều để hiểu đầy đủ các khái niệm này.
Một DatePickerDialog sẽ xem xét khác nhau dựa trên mức độ mà bạn đặt vào targetSDKversion AndroidManifest.xml hồ sơ của ( <uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>
). Nếu bạn đặt giá trị 10 hoặc thấp hơn, DatePickerDialog của bạn sẽ trông như trái. Mặt khác, nếu bạn đặt giá trị 11 trở lên, DatePickerDialog sẽ trông giống như đúng, với cùng một mã .
Mã mà tôi đã sử dụng để tạo mẫu này là siêu đơn giản. MainActivity.java
nhìn :
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickButton(View v) {
DatePickerDialog d = new DatePickerDialog(this, null, 2014, 5, 4);
d.show();
}
}
Và activity_main.xml
ngoại hình:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickButton"
android:text="Button" />
</RelativeLayout>
Đó là nó. Đó thực sự là mọi mã mà tôi cần để kiểm tra điều này.
Và sự thay đổi về giao diện này rất rõ ràng khi bạn nhìn thấy mã nguồn khung Android . Nó như sau:
public DatePickerDialog(Context context,
OnDateSetListener callBack,
int year,
int monthOfYear,
int dayOfMonth,
boolean yearOptional) {
this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
: com.android.internal.R.style.Theme_Dialog_Alert,
callBack, year, monthOfYear, dayOfMonth, yearOptional);
}
Như bạn có thể thấy, khung công tác nhận được targetSDKversion hiện tại và đặt chủ đề khác nhau. Loại đoạn mã này ( getApplicationInfo().targetSdkVersion >= SOME_VERSION
) có thể được tìm thấy ở đây và ở đó trong khung Android.
Một ví dụ khác là về lớp WebView . Các phương thức công khai của lớp Webview nên được gọi trên luồng chính và nếu không, hệ thống thời gian chạy sẽ ném a RuntimeException
, khi bạn đặt targetSDKversion 18 trở lên. Hành vi này có thể được phân phối rõ ràng với mã nguồn của nó . Nó chỉ được viết như thế.
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
if (sEnforceThreadChecking) {
throw new RuntimeException(throwable);
}
Tài liệu Android cho biết: " Khi Android phát triển với mỗi phiên bản mới, một số hành vi và thậm chí xuất hiện có thể thay đổi ." Vì vậy, chúng tôi đã xem xét hành vi và ngoại hình thay đổi và cách thay đổi đó được thực hiện.
Tóm lại, tài liệu Android cho biết " Thuộc tính này (targetSdkVersion) thông báo cho hệ thống mà bạn đã kiểm tra so với phiên bản đích và hệ thống không được kích hoạt bất kỳ hành vi tương thích nào để duy trì khả năng tương thích về phía trước của ứng dụng với phiên bản đích. " Điều này thực sự rõ ràng với trường hợp WebView. Sẽ ổn cho đến khi JELLY_BESE_MR2 được phát hành để gọi phương thức công khai của lớp WebView trên luồng không chính. Sẽ là vô nghĩa nếu khung Android ném một RuntimeException trên các thiết bị JELLY_BESE_MR2. Nó chỉ không nên kích hoạt các hành vi mới được giới thiệu vì lợi ích của nó, gây ra kết quả nghiêm trọng. Vì vậy, những gì chúng ta phải làm là kiểm tra xem mọi thứ có ổn trên một số TargetSDKversions không. Chúng tôi nhận được lợi ích như cải thiện ngoại hình bằng cách đặt targetSDKversion cao hơn,
EDIT: từ chối trách nhiệm. Hàm tạo DatePickerDialog đặt các chủ đề khác nhau dựa trên targetSDKversion hiện tại (mà tôi đã trình bày ở trên) thực sự đã được thay đổi trong lần xác nhận sau . Tuy nhiên, tôi đã sử dụng ví dụ đó, vì logic không bị thay đổi và đoạn mã đó hiển thị rõ ràng khái niệm targetSDKversion.
Đối với những người muốn một bản tóm tắt,
android:minSdkVersion
là phiên bản tối thiểu cho đến khi ứng dụng của bạn hỗ trợ. Nếu thiết bị của bạn có phiên bản Android thấp hơn, ứng dụng sẽ không cài đặt.
trong khi,
android:targetSdkVersion
là cấp API cho đến khi ứng dụng của bạn được thiết kế để chạy. Có nghĩa là, hệ thống điện thoại của bạn không cần sử dụng bất kỳ hành vi tương thích nào để duy trì khả năng tương thích về phía trước vì bạn đã thử nghiệm cho đến API này.
Ứng dụng của bạn vẫn sẽ chạy trên các phiên bản Android cao hơn so với được cung cấp targetSdkVersion
nhưng hành vi tương thích Android sẽ khởi động.
Freebie -
android:maxSdkVersion
nếu phiên bản API của thiết bị của bạn cao hơn, ứng dụng sẽ không cài đặt. I E. đây là API tối đa cho đến khi bạn cho phép ứng dụng của mình cài đặt.
I E. đối với MinSDK -4, maxSDK - 8, targetSDK - 8 Ứng dụng của tôi sẽ hoạt động ở mức tối thiểu 1.6 nhưng tôi cũng đã sử dụng các tính năng chỉ được hỗ trợ trong 2.2 sẽ hiển thị nếu được cài đặt trên thiết bị 2.2. Ngoài ra, đối với maxSDK - 8, ứng dụng này sẽ không cài đặt trên điện thoại sử dụng API> 8.
Tại thời điểm viết câu trả lời này, tài liệu Android không làm tốt công việc giải thích nó. Bây giờ nó được giải thích rất tốt. Kiểm tra nó ở đây
Nếu bạn nhận được một số lỗi biên dịch chẳng hạn:
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
.
private void methodThatRequiresAPI11() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.ARGB_8888; // API Level 1
options.inSampleSize = 8; // API Level 1
options.inBitmap = bitmap; // **API Level 11**
//...
}
Bạn nhận được lỗi biên dịch:
Trường yêu cầu API cấp 11 (tối thiểu hiện tại là 10): android.graphics.BitmapFactory $ Tùy chọn # inBitmap
Vì phiên bản 17 của Công cụ phát triển Android (ADT), có một chú thích mới và rất hữu ích @TargetApi
có thể khắc phục điều này rất dễ dàng. Thêm nó trước phương thức kèm theo khai báo có vấn đề:
@TargetApi
private void methodThatRequiresAPI11() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.ARGB_8888; // API Level 1
options.inSampleSize = 8; // API Level 1
// This will avoid exception NoSuchFieldError (or NoSuchMethodError) at runtime.
if (Integer.valueOf(android.os.Build.VERSION.SDK) >= android.os.Build.VERSION_CODES.HONEYCOMB) {
options.inBitmap = bitmap; // **API Level 11**
//...
}
}
Không có lỗi biên dịch ngay bây giờ và nó sẽ chạy!
EDIT: Điều này sẽ dẫn đến lỗi thời gian chạy ở mức API thấp hơn 11. Trên 11 hoặc cao hơn, nó sẽ chạy mà không gặp vấn đề gì. Vì vậy, bạn phải chắc chắn rằng bạn gọi phương thức này trên một đường dẫn thực thi được bảo vệ bởi kiểm tra phiên bản. TargetApi chỉ cho phép bạn biên dịch nó nhưng bạn tự chịu rủi ro.
android:minSdkVersion
và android:targetSdkVersion
cả hai đều là giá trị Integer, chúng ta cần khai báo trong tệp kê khai Android nhưng cả hai đều có các thuộc tính khác nhau.
android:minSdkVersion:
Đây là mức API yêu cầu tối thiểu để chạy ứng dụng Android. Nếu chúng tôi sẽ cài đặt cùng một ứng dụng trên phiên bản API thấp hơn, lỗi trình phân tích cú pháp sẽ xuất hiện và ứng dụng không hỗ trợ sẽ xuất hiện.
android:targetSdkVersion:
Phiên bản sdk mục tiêu là để đặt cấp độ API mục tiêu của ứng dụng. nếu thuộc tính này không được khai báo trong tệp kê khai, phiên bản minSdk sẽ là Phiên bản TargetSdk của bạn. Điều này luôn đúng là "cài đặt hỗ trợ ứng dụng trên tất cả các phiên bản API cao hơn mà chúng tôi đã khai báo là Phiên bản TargetSdk". Để làm cho ứng dụng bị giới hạn mục tiêu, chúng tôi cần khai báo maxSdkVersion trong tệp kê khai của chúng tôi ...
Nếu bạn đang tạo các ứng dụng yêu cầu quyền nguy hiểm và đặt targetSDK thành 23 trở lên, bạn nên cẩn thận. Nếu bạn không kiểm tra quyền trong thời gian chạy, bạn sẽ nhận được SecurityException và nếu bạn đang sử dụng mã bên trong khối thử, ví dụ như mở camera, có thể khó phát hiện lỗi nếu bạn không kiểm tra logcat.
Sdk mục tiêu là phiên bản bạn muốn nhắm mục tiêu và tối thiểu sdk là phiên bản tối thiểu.