Android開(kāi)發(fā)踩坑及最佳實(shí)踐(工作踩坑記錄 持續(xù)更新...)

音頻相關(guān):

1)Vivo X9 發(fā)現(xiàn)使用usb安裝時(shí),提示無(wú)法解析包,需在setting中禁用install run

  1. oppo R7s(4.4) Vivo X9(7.1) 錘子手機(jī)(7.1)等在權(quán)限管理時(shí)都有各自的處理方式,其中 oppo R7s會(huì)檢測(cè)Api方法的調(diào)用,后兩個(gè)手機(jī)有I管家和 安全中心, 在管家和安全中心未授權(quán)時(shí),檢測(cè)權(quán)限仍然是已獲得權(quán)限的狀態(tài),此時(shí)需要設(shè)置定時(shí)器,檢查操作是否執(zhí)行成功,比如音頻流

3)因?yàn)镺ppo R7s(4.4) 和錘子(7.1.1)以及其他低于6.0的機(jī)型,在權(quán)限管理時(shí)做了系統(tǒng)Rom級(jí)別的個(gè)性化定制。為了兼容這些權(quán)限獲取邏輯,在點(diǎn)擊錄音按鈕時(shí),會(huì)先開(kāi)啟錄音,同時(shí)開(kāi)啟定時(shí)器檢查,錄音文件里有沒(méi)有內(nèi)容

(沒(méi)有權(quán)限的話,就沒(méi)有內(nèi)容,有權(quán)限,就有內(nèi)容)。如果錄音文件有內(nèi)容說(shuō)明有權(quán)限,就正常錄音,如果錄音文件沒(méi)有內(nèi)容,輪詢10s 還是如此的話,就將定時(shí)器和錄音停掉。

4) 但是 Vivo X9 手機(jī)即使沒(méi)有錄音權(quán)限, 還是可以將音頻流寫入文件,所以除了要判斷文件length還需要判斷 //audioChunk.maxAmplitude() 其值一直為-2.147483648E9

5)實(shí)現(xiàn)音頻轉(zhuǎn)碼由ffmpeg 改為 Lame提高wav轉(zhuǎn)MP3的效率
在wav音頻經(jīng)過(guò)SoundTouch變聲,再經(jīng)過(guò)Lame 轉(zhuǎn)mp3時(shí),會(huì)啪 的一聲,
解決方式是跳過(guò)前面500 到 4096字節(jié)的流的寫入(Wav header )即Wav頭不寫入。

6)音頻錄制和covertWav2Mp3的過(guò)程中,音頻文件一直被占用或者outputStream忘記close,導(dǎo)致在Oppo R7s上, 音頻可以被刪除,但是下次創(chuàng)建時(shí),會(huì)出現(xiàn)netease_audio_night變成不可識(shí)別目錄文件的問(wèn)題

其他:
1)使用MediaPlayer播放網(wǎng)絡(luò)音頻時(shí),要選用prePareAsync的方式,如果使用prepare方式,在無(wú)網(wǎng)絡(luò)時(shí),會(huì)播放阻塞造成ANR

2)在使用SoundTouch時(shí), 在gradle build 時(shí)提示 ndK編譯
error: undefined reference to '__atomic_fetch_add_4'
需要在Android.mk中 加入LOCAL_LDLIBS += -latomic

3)以后在ViewHolder中 想知道某個(gè)View的寬高,或者想知道這個(gè)View layout 完成,使用addOnLayoutChangeListener 而不是viewTree 的GlobleLayout

關(guān)于RecycleView

發(fā)現(xiàn)一個(gè)有趣的事情,復(fù)寫ViewHolder.Adapter中的 onViewAttachToWindow 和 onViewDetachFromWindow (不管是LinearLayoutManager 還是GridLayoutManager)

1)該Adapter可見(jiàn)的Item中存在定時(shí)器在執(zhí)行,且最后一個(gè)ViewHolder的View Item如果只顯示了一半,

  1. 必須要在第一屏,或者在第一屏下面的一兩條數(shù)據(jù)

3)在滿足1) 2)的條件下,這個(gè)ViewHolder 會(huì)一直觸發(fā) onViewAttachToWindow 和 onViewDetachFromWindow

4)只有當(dāng)一個(gè)ViewHolder的Item 的這一行全部顯示的時(shí)候(沒(méi)有被遮擋) 該ViewHolder的onViewAttachToWindow方法才會(huì)被執(zhí)行

5)只有當(dāng)一個(gè)ViewHolder的Item的這一行 完全不顯示的時(shí)候(一點(diǎn)都不顯示) 該ViewHolder的onViewDetachFromWindow方法才會(huì)執(zhí)行

  1. 緩存的ViewHolder的數(shù)目,會(huì)比 Visible 的Item 的數(shù)目多,比如可見(jiàn)item 9個(gè),那么創(chuàng)建的ViewHolder的數(shù)目>9 在展示第11條數(shù)據(jù)的時(shí)候

第11條ViewHolder會(huì)復(fù)用第0條ViewHolder 第0條ViewHolder的 onViewRecycled方法會(huì)執(zhí)行

  • 使用 setCompoundDrawablesWithIntrinsicBounds 而不是
    setCompoundDrawables
  • https://juejin.im/post/5a3a70d46fb9a044fe46855d
    這個(gè)
    dartDebug {
    matchingFallbacks = ['release','debug']
    isDartDebug = true
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    } 很有用?。?!
  • 每次提交到FlutterLab后, 需要在智造項(xiàng)目調(diào)用git submodule update --remote
    然后再提交到智造項(xiàng)目,這樣智造項(xiàng)目里的FlutterLab才會(huì)同步為最新的代碼。

打包機(jī)的問(wèn)題就是,在FlutterLab刪除了local property之后 ,沒(méi)有同步update到智造項(xiàng)目并提交,導(dǎo)致Local Property 一直存在。
同時(shí)修改.android 中的Flutter文件夾下的build.gradle文件:
println System.getenv('FLUTTER_ROOT')

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
flutterRoot = System.getenv('FLUTTER_ROOT')
}

if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with
flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment
variable.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
就可以避免每個(gè)人LocalProperty中的Flutter Sdk路徑不一致的問(wèn)題

  • 發(fā)現(xiàn)selector里的 設(shè)置順序也會(huì)有影響, 應(yīng)該要把 disable之類的放前面,否則設(shè)置無(wú)效。
  • base依賴 resource 和 Solution 。如果base 的buildType設(shè)置為3個(gè),那么
    Resource 和 Solution 的buildType也要改為對(duì)應(yīng)的3個(gè)
  • 引入AAr時(shí),子項(xiàng)目
    repositories {
    flatDir {
    dirs 'libs'
    }
    }

主項(xiàng)目:

repositories {
//第一個(gè)libs是主項(xiàng)目的libs,其他module的libs路徑需要用逗號(hào)隔開(kāi)../module
名/libs
flatDir {
dirs 'libs', '../sweeper/libs'
}
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容