無關(guān)技術(shù)
日日行,不怕千萬里;
時(shí)時(shí)做,不怕千萬事.
本章概要
本章主要講了SDK的相關(guān)版本和兼容性的問題.
SDK最低版本
以最低版本設(shè)置為標(biāo)準(zhǔn),操作系統(tǒng)會(huì)拒絕將應(yīng)用安裝在系統(tǒng)版本低于標(biāo)準(zhǔn)的設(shè)備上.
比如設(shè)置最低版本為19.在Android系統(tǒng)低于19的設(shè)備上都是拒絕安裝此應(yīng)用的.
SDK目標(biāo)版本
目標(biāo)版本的設(shè)定值告知android:應(yīng)用是為哪個(gè)API級(jí)別設(shè)計(jì)的.
大多數(shù)情況下,目標(biāo)版本即最新發(fā)布的android版本.
但是,新發(fā)布的sdk版本可能會(huì)改變應(yīng)用在設(shè)備上的顯示方式,或者運(yùn)行行為也改變了.
這時(shí)候可以降低目標(biāo)版本.比如android 6.0 權(quán)限行為,7.0以上的fileProvider等
有些第三方庫的影響等等,只好降低目標(biāo)版本到22.運(yùn)行正常.
降低sdk目標(biāo)版本可以保證的是:即便在高于目標(biāo)版本的設(shè)備上,應(yīng)用仍然可以正常運(yùn)行,且運(yùn)行行為與目標(biāo)版本一致.但是新版本總的變化已經(jīng)被忽略了.
SDK編譯版本
sdk最低版本和sdk目標(biāo)版本會(huì)通知給操作系統(tǒng),而sdk編譯版本只是你和編譯器之間的私有信息.
編譯代碼時(shí),sdk編譯版本指定具體要使用的系統(tǒng)版本.
安全添加新版本API中的代碼
最低版本和編譯版本的差異較大,由此帶來的問題需要解決.比如,你的手機(jī)是4.4的API級(jí)別是19. 你的代碼中使用了API19以后的sdk版本中代碼,那么運(yùn)行時(shí),你的應(yīng)用就會(huì)奔潰.
受益于android Lint,這類問題,會(huì)有提示.
挑戰(zhàn)練習(xí)
顯示設(shè)備運(yùn)行系統(tǒng)的api級(jí)別
應(yīng)用運(yùn)行時(shí),調(diào)用Build.Version.SDK_INT 就是運(yùn)行的版本.
所以可以使用如下代碼
`
mApiVersionTextView = findViewById(R.id.api_version_text_view);
String apiLevel = getString(R.string.api_level, Build.VERSION.SDK_INT);
mApiVersionTextView.setText(apiLevel);
`
其中TextView的布局
`
<TextView
android:id="@+id/api_version_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/api_level"
/>
`
限制作弊次數(shù)
思路:聲明一個(gè)int值mCheatCount,用于記錄用戶作弊的次數(shù),每次作弊的時(shí)候,都會(huì)在onActivityResult記錄,可以在改方法中遞增這個(gè)值.
要考慮到屏幕旋轉(zhuǎn)等的問題,需要在上一個(gè)(05)章節(jié)完成挑戰(zhàn)練習(xí)中的基礎(chǔ)上來做這道題.
`
if (mIsCheaters[mCurrentIndex]) {
mCheatCount++;
mRemainCountTextView.setText("remain cheat count:" + (3 - mCheatCount));
}
`
這種方法雖然實(shí)現(xiàn)了,但是正常情況下,應(yīng)該是同一道題,我查看答案了,應(yīng)該下次再來查看,是不應(yīng)該記錄作弊的次數(shù)的.
首先想到的是聲明一個(gè)int值mLastPosition,默認(rèn)為-1,
當(dāng)這個(gè)值不等于當(dāng)前索引的值,才去遞增mCheatCount.
實(shí)現(xiàn)如下:
`
if (mIsCheaters[mCurrentIndex] && mLastPosition != mCurrentIndex) {
mCheatCount++;
mLastPosition = mCurrentIndex;
mRemainCountTextView.setText("remain cheat count:" + (3 - mCheatCount));
}
`
后來想想,這樣做是有問題的,比如第一道題作弊了(mLastPosition=0),然后點(diǎn)擊下一道題,也作弊了(mLastPosition =1).然后多次點(diǎn)擊next按鈕,回到第一道題,再去作弊.
這時(shí)候mLastPosition( = 1) != mCurrentIndex(= 0)條件成立,而明明第一道題已經(jīng)作弊了,再次查看不應(yīng)該記錄作弊次數(shù)才對(duì)的.
所以想到要用數(shù)組來記錄作弊與否.
聲明一個(gè)boolean數(shù)組,默認(rèn)值都是false,當(dāng)用戶作弊后,就將當(dāng)前索引的值改為true
此時(shí)如果用戶作弊了,還需要滿足當(dāng)前索引值的boolean,為false才去遞增作弊次數(shù).
`
mIsCheaters[mCurrentIndex] = CheatActivity.wasAnswerShown(data);
if (mIsCheaters[mCurrentIndex] && !mCheatCounts[mCurrentIndex]) {
mCheatCount++;
// mLastPosition = mCurrentIndex;
mCheatCounts[mCurrentIndex] = true;
mRemainCountTextView.setText("remain cheat count:" + (3 - mCheatCount));
}
`
考慮到屏幕旋轉(zhuǎn)的問題,應(yīng)該將這些值,都保存在bundle中.
按鈕的禁用就很容易了,只需要判斷作弊次數(shù)>=3,就將按鈕設(shè)置為不可用.
當(dāng)然,防止屏幕旋轉(zhuǎn),需要聲明一個(gè)boolean來保存按鈕的可用性.然后將這個(gè)值保存在bundle中.