開(kāi)發(fā)最佳實(shí)踐與兼容性建議(適配常見(jiàn)問(wèn)題)

MIUI是基于Android深度定制的操作系統(tǒng),和Android保持100%兼容,我們準(zhǔn)備了一些在Android開(kāi)發(fā)過(guò)程中哦給你可能遇到的問(wèn)題,也許對(duì)您有所幫助。

如果在基于MIUI進(jìn)行開(kāi)發(fā)、測(cè)試的過(guò)程中遇到問(wèn)題,我們會(huì)竭盡所能協(xié)助開(kāi)發(fā)者解決。在和開(kāi)發(fā)者溝通的過(guò)程中,我們發(fā)現(xiàn),很多應(yīng)用遇到的問(wèn)題,并非因MIUI導(dǎo)致,而是對(duì)Android本身。

1.盡量用Android標(biāo)準(zhǔn)的接口,最好不要很“聰明”的讀取較為底層的數(shù)據(jù)

每個(gè)手機(jī)的底層都有可能有自己獨(dú)特的實(shí)現(xiàn),這種特殊性,其實(shí)是對(duì)開(kāi)發(fā)者屏蔽的,開(kāi)發(fā)者直接利用,有時(shí)會(huì)得不到期望的效果。

比如之前我們發(fā)現(xiàn)一款app,會(huì)直接讀取底層frame buffer,然后以錄像的方式顯示當(dāng)前屏幕,但是由于我們frame buffer的特殊性,結(jié)果它讀出來(lái)的就是兩三段斷開(kāi)的屏幕。

再比如,有些游戲會(huì)直接從底層的讀取motion event,然后自己再根據(jù)這些事件做些相應(yīng)操作,但這些事件未經(jīng)過(guò)android處理,結(jié)果就有可能有問(wèn)題。

2.要和Android版本保持一致

Android隨著版本的升級(jí),會(huì)有些向后兼容性不好。常見(jiàn)現(xiàn)象是,本來(lái)在較低版本上正常運(yùn)行的app,在較高版本上運(yùn)行失敗。

一個(gè)常見(jiàn)的問(wèn)題是權(quán)限相關(guān),比如WRITE_APN_SETTINGS這個(gè)權(quán)限是在某個(gè)版本上加進(jìn)去的,若app不申請(qǐng)此權(quán)限,在之前Android版本可正常運(yùn)行,但是一旦Android升級(jí),app就會(huì)因?yàn)槿狈?quán)限而FC。

3. NDK版本

有些app可能是用NDK開(kāi)發(fā)的,對(duì)于這樣的app,一定要在對(duì)應(yīng)的NDK版本下編譯測(cè)試,否則極有可能出現(xiàn)莫名其妙的問(wèn)題。

比如,我們之前和某播放器應(yīng)用聯(lián)調(diào)過(guò)一個(gè)問(wèn)題:該播放器在MIUI上播放一段時(shí)間后,立即卡死,當(dāng)時(shí)我們調(diào)試了好久,懷疑SurfaceFlinger,懷疑播放器本身,等等,各種調(diào)試,無(wú)果。

最終,還是發(fā)現(xiàn)是由于該播放器編譯時(shí),NDK版本不對(duì)。

4. 一定要釋放資源

一些資源,比如WakeLock,WifiLock,F(xiàn)ile descriptor,Cursor等一定要釋放,這些資源甚至?xí)绊懙饺帧1热鏦akeLock和WifiLock會(huì)影響屏幕和Wifi的休眠,從而導(dǎo)致耗電。

而Cursor,尤其是一些較為常用的Provider獲得的Cursor,長(zhǎng)期不關(guān)閉,有可能會(huì)導(dǎo)致該P(yáng)rovider無(wú)法工作。

5. 耗電操作

慎用某些對(duì)耗電敏感的操作,比如Alarm,比如頻繁掃描Wifi,一定要考慮這些操作的極端最壞情況。比如,之前我們手機(jī)上某NetworkProvider導(dǎo)致手機(jī)空置狀態(tài)下,比以前成倍的耗電。原因就是,Alarm不斷喚醒手機(jī),每次喚醒又不斷的掃描Wifi。

對(duì)于有后臺(tái)Service的,確保該service只在必要情況下運(yùn)行,而不會(huì)一直運(yùn)行,可以用strace查看下app的活動(dòng)狀態(tài)

6. 在MIUI上出現(xiàn)問(wèn)題后,排查的手段

  • 首先看原生系統(tǒng)上有無(wú)問(wèn)題\ 找對(duì)應(yīng)的Nexus 4或者Galaxy Nexus等,看看是否有相同問(wèn)題,若有,基本確定是app自身問(wèn)題,否則有可能和MIUI有關(guān)

  • MIUI對(duì)權(quán)限控制較為嚴(yán)格: 若出現(xiàn)問(wèn)題,可先看看授權(quán)管理,打開(kāi)相應(yīng)權(quán)限

  • 若確定為MIUI問(wèn)題,可以和我們聯(lián)系,我們會(huì)竭盡全力幫助您解決問(wèn)題之前我們?cè)鴧f(xié)助啪啪、暴風(fēng)影音、唱吧以及其它個(gè)人開(kāi)發(fā)者或者終端用戶(hù)調(diào)研過(guò)遇到的問(wèn)題,均得到較好的解決方法。

常見(jiàn)問(wèn)題

1、為什么在Manifest聲明了android.permission.INTERNET還是無(wú)法訪問(wèn)網(wǎng)絡(luò)?

安全中心-網(wǎng)絡(luò)助手里為用戶(hù)提供了網(wǎng)絡(luò)控制功能,如果把A應(yīng)用的移動(dòng)網(wǎng)絡(luò)權(quán)限或者WIFI網(wǎng)絡(luò)權(quán)限禁用了,那么在調(diào)用網(wǎng)絡(luò)請(qǐng)求的時(shí)候會(huì)拋出異常:java.net.ConnectException: socket failed: EACCES (Permission denied)

2、為什么無(wú)法訪問(wèn)環(huán)回地址(127.0.0.1)?

安全中心-網(wǎng)絡(luò)助手里為用戶(hù)提供了網(wǎng)絡(luò)控制功能,如果把A應(yīng)用的移動(dòng)網(wǎng)絡(luò)權(quán)限禁用,則該應(yīng)用訪問(wèn)環(huán)回地址失敗。

3、為什么我的應(yīng)用在開(kāi)啟騷擾攔截之后收不到驗(yàn)證短信?

騷擾攔截有智能引擎的判斷,在開(kāi)啟智能攔截后我們會(huì)識(shí)別某些帶有騷擾短信特征的短信。如果您認(rèn)為您的短信被誤判,可以聯(lián)系我們。strong text####4、為什么我的應(yīng)用發(fā)起的回?fù)茈娫挄?huì)被攔截?回?fù)茈娫捰袃煞N:一種是空號(hào)碼,騷擾攔截有空號(hào)碼攔截,在用戶(hù)手動(dòng)設(shè)置之后會(huì)攔截空號(hào)碼。一種是正常號(hào)碼,騷擾攔截有標(biāo)記攔截的功能,在開(kāi)啟標(biāo)記攔截且該號(hào)碼被多次標(biāo)記拉黑則會(huì)被攔截。

5、為什么我的應(yīng)用申請(qǐng)使用su命令會(huì)失敗?

一、MIUI的穩(wěn)定版沒(méi)有root權(quán)限。二、開(kāi)發(fā)版有root權(quán)限,但是受手機(jī)端App安全中心控制。如果您需要您的應(yīng)用開(kāi)啟某項(xiàng)權(quán)限,可以引導(dǎo)用戶(hù)跳轉(zhuǎn)應(yīng)用權(quán)限管理頁(yè)面由用戶(hù)手動(dòng)開(kāi)啟。Intent intent = new Intent(); intent.setAction("miui.intent.action.ROOT_MANAGER"); intent.addCategory(Intent.CATEGORY_DEFAULT); 三、一些應(yīng)用在獲取root權(quán)限后,會(huì)修改系統(tǒng)的su等文件,導(dǎo)致其他應(yīng)用的root不可用。

6、為什么我在Manifest聲明了權(quán)限,依然不能控制Wifi,Gps,顯示懸浮窗等?

安全中心會(huì)控制權(quán)限的使用,如果需要開(kāi)放某個(gè)權(quán)限,可以在安全中心-授權(quán)管理-應(yīng)用權(quán)限管理內(nèi)修改。我們會(huì)根據(jù)應(yīng)用的主要功能開(kāi)放權(quán)限,如果您的應(yīng)用有權(quán)限控制方面的問(wèn)題,請(qǐng)聯(lián)系我們。

7、如何獲取某項(xiàng)權(quán)限是否開(kāi)啟?

暫時(shí)沒(méi)有這個(gè)查詢(xún)接口,如果您需要您的應(yīng)用開(kāi)啟某項(xiàng)權(quán)限,可以引導(dǎo)用戶(hù)跳轉(zhuǎn)應(yīng)用權(quán)限管理頁(yè)面由用戶(hù)手動(dòng)開(kāi)啟。 Intent intent = new Intent(); intent.setAction("miui.intent.action.APP_PERM_EDITOR"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.putExtra("extra_pkgname", "應(yīng)用包名");

8、為什么我的Alarm不太精確?

Google和MIUI都啟用了對(duì)齊喚醒功能,會(huì)把一小段時(shí)間內(nèi)的Alarm對(duì)齊到某個(gè)Alarm的時(shí)間點(diǎn)一起執(zhí)行,達(dá)到省電的目的。

9、我的應(yīng)用為什么不能自啟動(dòng)?

在MIUI上應(yīng)用的自啟動(dòng)由用戶(hù)進(jìn)行控制,默認(rèn)不開(kāi)放自啟動(dòng)權(quán)限,其中自啟動(dòng)包含開(kāi)機(jī)自啟動(dòng)和接收系統(tǒng)廣播等方式啟動(dòng),但是由A應(yīng)用啟動(dòng)B應(yīng)用則不受限制。如果您需要您的應(yīng)用自啟動(dòng),可以引導(dǎo)用戶(hù)跳轉(zhuǎn)自啟動(dòng)管理頁(yè)面由用戶(hù)手動(dòng)開(kāi)啟。 Intent intent = new Intent();\ intent.setAction("miui.intent.action.OP_AUTO_START"); intent.addCategory(Intent.CATEGORY_DEFAULT);

10、如何在快捷方式圖標(biāo)上顯示未讀消息的數(shù)字?

請(qǐng)參看:Android系統(tǒng) 小米/三星/索尼快鍵圖標(biāo)BadgeNumber數(shù)字提醒

11、如何將我的音樂(lè)播放器控件集成到MIUI自帶的通知欄音樂(lè)控制中心去?

請(qǐng)參看:MIUI系統(tǒng)音樂(lè)控件標(biāo)準(zhǔn)化方案,第三方APP接入指南

12、我的應(yīng)用在小米應(yīng)用商店審核失敗怎么辦?

關(guān)于應(yīng)用審核問(wèn)題、認(rèn)領(lǐng)問(wèn)題、開(kāi)發(fā)者郵箱認(rèn)證問(wèn)題,以及其它關(guān)于小米應(yīng)用商店的運(yùn)營(yíng)問(wèn)題(除開(kāi)發(fā)中遇到的問(wèn)題),請(qǐng)聯(lián)系小米應(yīng)用商店開(kāi)發(fā)者支持郵箱:developer@xiaomi.com

13、添加了MIUI提供的沉浸式代碼后發(fā)現(xiàn)軟件盤(pán)是否彈出的狀態(tài)獲取不到以及android:windowSoftInputMode="adjustResize" 的設(shè)置無(wú)作用,該怎么解決?

這個(gè)問(wèn)題是android原生的問(wèn)題,我們的MIUISDK已經(jīng)解決。如果使用MIUISDK則不會(huì)出現(xiàn)此問(wèn)題。如果是在原生系統(tǒng)上開(kāi)發(fā),可以通過(guò)如下參考辦法繞過(guò)adjustResize無(wú)效,參考辦法:輸入法原來(lái)沉浸的方法繼續(xù)加上,然后在布局view上面設(shè)置setFitSystemWindow屬性為true,這樣 resize屬性會(huì)生效。但是view的頂部會(huì)預(yù)留出來(lái)狀態(tài)欄的高度。 再重寫(xiě)界面根view(應(yīng)用xml布局的頂層view)的fitSystemWindow函數(shù), 將頂部的padding去掉。 有點(diǎn)繞,但是效果出來(lái)是對(duì)的。

14、據(jù)說(shuō)雙卡雙待的功能不是安卓原生的功能,現(xiàn)在我需要調(diào)用系統(tǒng)撥打電話但沒(méi)有辦法控制使用那個(gè)卡來(lái)?yè)艽颍以撛趺唇鉀Q?

原生android在5.1之前本身是沒(méi)有雙卡方案,所以5.1之前的所有雙卡方案都是隨著平臺(tái)的不同而不同的。建議就按正常的單卡呼叫方案進(jìn)行,理論上會(huì)給用戶(hù)提示選擇用哪個(gè)卡進(jìn)行呼叫。而在原生android5.1及以后,android原生支持了雙卡,這個(gè)將是業(yè)界標(biāo)準(zhǔn)接口,按google方案即可。MIUI在開(kāi)發(fā)的時(shí)候有一個(gè)原則是,原生的所有對(duì)外基本接口,絕對(duì)不會(huì)修改。

15、如何調(diào)用小米4的紅外控制接口發(fā)送紅外數(shù)據(jù)?

請(qǐng)參看:https://developer.android.com/reference/android/hardware/ConsumerIrManager.html

16、MIUI 中的藍(lán)牙2.0和android 原生中的藍(lán)牙2.0有什么兼容性問(wèn)題嗎?

請(qǐng)參看:http://developer.android.com/guide/topics/connectivity/bluetooth.html

17、在SSL協(xié)議握手過(guò)程中出現(xiàn)的exception,該怎么解決?

可以通過(guò)如下方法排查: 1. 模擬器里網(wǎng)絡(luò)設(shè)置的是否正常,是否能上其他https的網(wǎng)站。2. 換個(gè)時(shí)間點(diǎn)試試,有可能是服務(wù)器端的問(wèn)題。 3. 更新下/system/lib/libssl.so文件

18、如何調(diào)用MIUI 6沉浸式狀態(tài)欄?

請(qǐng)參看:MIUI 6 沉浸式狀態(tài)欄調(diào)用方法

19、如何解決app在淺色背景的主題通知欄看不清通知的問(wèn)題?如何解決默認(rèn)系統(tǒng)通知欄處部分app字體顏色顯示不明顯問(wèn)題?

在MIUI系統(tǒng)中,通知欄的每一條通知的字體顏色(包括標(biāo)題、主次要文字、時(shí)間等)均使用原生Android規(guī)范,并未系統(tǒng)定義,故,建議各app參照原生Android規(guī)范來(lái)寫(xiě)字體,保證當(dāng)主題修改原生Android字體顏色時(shí),各app的通知顏色可隨之調(diào)整。

如下內(nèi)容請(qǐng)轉(zhuǎn)達(dá)給相應(yīng)開(kāi)發(fā)處理。要想文字跟隨主題變化,TextView需要用android原生的style 比如標(biāo)題的Textview可以加上android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title"

如果以上信息沒(méi)有對(duì)您有幫助的信息請(qǐng)您使用公司域名郵箱務(wù)必按照如下模板填寫(xiě)您反饋的問(wèn)題,

發(fā)送到第三方應(yīng)用開(kāi)發(fā)者反饋郵箱 miui-appfeedback@xiaomi.com

第三方應(yīng)用開(kāi)發(fā)者問(wèn)題反饋模板

郵件標(biāo)題:第三方應(yīng)用開(kāi)發(fā)者反饋:+問(wèn)題簡(jiǎn)述 郵件內(nèi)容:APP名稱(chēng): APP版本: 設(shè)備機(jī)型: 系統(tǒng)版本: 問(wèn)題描述: 代碼或log: 其它文件: 復(fù)制代碼