欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android bug最近遇到的幾個坑解決分享

 更新時間:2022年12月13日 09:05:21   作者:leobert-lan  
這篇文章主要為大家介紹了Android bug最近遇到的幾個坑解決分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

6-7月的事情著實有點多。沒有清風(fēng)亦沒有鮮花,連蟬都熱到燥不動了,人自然也變得慵懶了許多。

月頭計劃和諸君探討下Compose(Compose-Desktop)和MVI實際投產(chǎn)后的感受,眼看即將到月底,低頭看著才寫一半的草稿,沉默良久,大抵這個月是沒有希望成稿了。

終究,只能挑一些最近遇到的問題寫一寫,欺騙自己還未曾擺爛。

Android R、S中的外部文件管理權(quán)限

想來是舒適太久了,目前負責(zé)的核心項目均是面向特定Android-Pad開發(fā)的,在 Android 9 已經(jīng)躺了一年,已經(jīng)快忘記了 適配 這一祖?zhèn)靼ぁ?/p>

但還有部分即將推出的項目是面向普通用戶的,順便談一談這個 老問題

Android 10 中提出了分區(qū)存儲,對于外部存儲空間的讀寫,除了需要處理FileProvider外,還需要配置 requestLegacyExternalStorage 。

Android R、S 中,進行了更嚴(yán)格的限制,需要獲取完整的外部存儲控制權(quán)限。

作者按:筆者負責(zé)的項目受技術(shù)之外因素的影響,改變現(xiàn)有的文件存儲路徑的阻力非常大

判斷與申請完全的控制權(quán)限

補充聲明權(quán)限

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

那么,相關(guān)權(quán)限如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

并且需要運行時動態(tài)獲取權(quán)限,關(guān)鍵代碼如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        //略去引導(dǎo)彈窗等相關(guān)交互邏輯
        startActivityForResult(Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), REQ_CODE_FILE_MANAGE)
        return
    }
}
// do something

可以結(jié)合 ActivityResultContracts 改造 onActivityResult,不再贅述。

用戶對軟件授予權(quán)限后可讀寫文件。

如何快速改造

隨著Compose跨平臺技術(shù)越來越熱,將應(yīng)用的業(yè)務(wù)在多個平臺上復(fù)用也越發(fā)有價值,而平臺的差異性內(nèi)容應(yīng)當(dāng)在平臺內(nèi)部解決。

那么 如何在不修改Presenter/ViewModel 和 Model層的前提下,便捷的解決此類適配問題 越發(fā)具有價值。

當(dāng)然,此類問題的解決不能脫離實際空談,便不做具體展開。目前在項目中先運用了 Proxy 方式,對業(yè)務(wù)層追加了前置邏輯,進行了簡單處理。

我已經(jīng)設(shè)想了一個框架,并非PermissionX之類處理Android動態(tài)權(quán)限的框架,有后續(xù)實質(zhì)進展后再與諸君分享。

藍牙居然搜索不到設(shè)備

如果直接適配Android 12,大概率不會出現(xiàn)該問題(未經(jīng)過大量rom驗證),target是低版本,以往的業(yè)務(wù)代碼不到位就有可能受到影響

未適配Android 12 藍牙權(quán)限的應(yīng)用,在部分手機上發(fā)現(xiàn)未打開 "訪問我的位置信息" 時(不是定位權(quán)限?。。瑫?dǎo)致搜索不到藍牙設(shè)備。大抵是ROM廠商的杰作。

參考地圖類SDK的操作,增加以下檢測代碼:

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
    //引導(dǎo)用戶開啟定位:Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
}

在 target Android12 中:

  • 請求精確位置,需同時申請 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 權(quán)限
  • (動態(tài))申請藍牙相關(guān)權(quán)限時,不再需要申請設(shè)備位置信息相關(guān)權(quán)限

理論上不需要再加這一檢測,但仍需經(jīng)過大量ROM測試。建議保留該段檢測邏輯。

一個高star庫中的I/O和多線程的綜合性問題

前幾日和好友閑聊時,好友提到他們的項目中使用了一個開源的下載庫 Aria,但時不時會出現(xiàn)下載圖片失敗的問題,實質(zhì)是庫的bug。

閱讀源碼后感到問題出在細節(jié)知識上,本篇也需要水一下字數(shù),索性拿來討論一二。

庫中運用到的技術(shù):

  • 多線程&鎖
  • IO
  • Android的Handler

其中,多線程和鎖的知識本篇不談,我亦寫有相關(guān)系列;庫作者使用Android中的Handler簡化多線程間的通信,也不再展開;IO部分系統(tǒng)展開也很長,我已有系列文章計劃,本篇結(jié)合問題簡單談一談。

和文件服務(wù)器對比,移動端的文件上傳下載并發(fā)量很小,其速度制約一般在于:服務(wù)器單連接流量限制,網(wǎng)絡(luò)條件。

對于單個文件采用多線程方式上傳、下載,只能突破 單連接流量限制,以充分使用網(wǎng)絡(luò)資源。多個文件并行上下載的產(chǎn)品意義遠大于充分吃掉網(wǎng)絡(luò)帶寬資源。

注意:上下載的高帶寬占用一定程度上會影響其他網(wǎng)絡(luò)層業(yè)務(wù)

一般對于下載而言,使用多線程時用常規(guī)的 "碎文件合并" 的思路即可。用 RandomAccessFile并不是一個好主意。

多線程寫RandomAccessFile并非一件很美好的事情,以后的文章中細聊

在使用Java經(jīng)典IO時,使用Buffer減少IO次數(shù)可以獲得很好的性能提升,需要注意及時 flush,該庫中用Buffer設(shè)計對 RandomAccessFile 進行了一層封裝。想來也是源自三方庫.

將部分代碼簡化后類似如下代碼:

class Demo {
    @Test
    fun mockDownload() {
        Looper.prepare()
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        val file = File(appContext.cacheDir, "testtmp")
        if (file.exists()) {
            file.delete()
        }
        file.createNewFile()
        assertEquals(0, file.length())
        val data = "hello".encodeToByteArray()
        val bFile = BufferedRandomAccessFile(file, "rwd", 1024)
        val handler = object : Handler(Looper.myLooper()) {
            override fun handleMessage(msg: Message?) {
                super.handleMessage(msg)
                //模擬文件合并線程,僅斷言文件大小
                if (msg?.what == 1) {
                    assertEquals(data.size.toLong(), file.length())
                    Looper.myLooper()?.quit()
                }
            }
        }
        //模擬下載線程
        thread(priority = 1) {
            val ins = ByteArrayInputStream(data)
            try {
                val buffer = ByteArray(1024)
                var len: Int
                while (ins.read(buffer).also { len = it } != -1) {
                    bFile.write(buffer, 0, len)
                }
                //模擬下載完成消息
                handler.sendEmptyMessage(1)
//                Thread.yield() -- 模擬一下線程被切換或者因為鎖導(dǎo)致的同步
            } finally {
                ins.close()
//                bFile.flush() will be invoked in close
                bFile.close()
            }
        }
        Looper.loop()
    }
}

觀察這段代碼可以發(fā)現(xiàn),存在不安全因素:最后一個buffer塊的內(nèi)容大小未必是1024,需等到 bFile.close()時方可寫入文件。

雖然 handler.sendEmptyMessage(1) 發(fā)送的消息會被異步執(zhí)行,但并不意味著 bFile.close() 一定會先執(zhí)行。鎖、AQS、系統(tǒng)線程調(diào)度等均可能會導(dǎo)致該問題。

以上就是Android bug最近遇到的幾個坑解決分享的詳細內(nèi)容,更多關(guān)于Android bug解決的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論