原创 FileProvider的一些事 文件URI 打開文件 系統應用使用FileProvider的坑 直接傳遞ParcelFileDescriptor

高版本的android對文件權限的管控抓的很嚴格,理論上兩個應用之間的文件傳遞現在都應該是用FileProvider去實現,這篇博客來一起了解下它的實現原理。 首先我們要明確一點,FileProvider就是一個ContentProvide

原创 記一個線程阻塞問題的分析過程 Long monitor contention kill -3 命令 schedstat 線程鎖定位

最近遇到了一個線程阻塞的問題,分析的過程比較有代表性,這裏做個總結分享下。 測試報的問題是: 概率性出現開機的前幾分鐘我們的服務不可用。 查看日誌發現開機之後的幾分鐘之內mqtt庫不斷在斷開、重連broker。MqttCallback.di

原创 FFmpeg入門 - 格式轉換 音頻分⽚(plane)與打包(packed) 音頻數據的實際長度 音頻格式轉換 視頻格式轉換 AVFrame內存管理機制 align 完整代碼

我們現在已經能在安卓上播放視頻畫面了,但是聲音部分還是缺失的,這篇博客就來把視頻的音頻播放模塊也加上。 爲了音頻和視頻可以分別解碼播放,我們需要對之前的代碼做重構,將媒體流的讀取和解碼解耦: MediaReader從文件流中讀取出AVPa

原创 當Gson遇上data class Gson解析流程 非空類型失效和構造函數不會被調用的原理 全部成員都有默認值的情況 解決思路

當Gson遇上kotlin data class,會發生一些很有意思的現象: 現象1: 非空類型失效 data class TestData( val a: String, val b: String ) val data

原创 Jni多線程與類加載 native子線程加載不了自定義的Class 解決方法

在JNI中我們可以通過JNIEnv的FindClass方法查找到java的類然後進行類似反射的調用。 如果通過java代碼調用的Jni函數,此時c的函數與Java運行在同一個線程中。無論是在主線程還是java啓動的子線程中FindClass

原创 安卓系統的啓動流程與各種死法 系統啓動流程 系統奔潰重啓流程 系統開機之後死掉 系統開機死掉導致開不了機 總結

最近遇到了蠻多framework掛掉引發的問題,這裏做個總結分享.在看具體bug之前先簡單瞭解下安卓系統的啓動流程可以幫助我們定位和分析問題: 系統啓動流程 開機的流程圖如下: 大概的步驟爲: 啓動BootLoader: 開機引導可以初

原创 Android多用戶的一些坑 android:singleUser配置 android:exported被自動關閉 全局浮動框在子用戶不顯示 結尾吐槽

最近關於多用戶功能報了幾個bug,我覺得蠻有意思的這裏記錄一下。 起因是是測試報了打開了多用戶功能並且切到另外一個用戶之後,系統功能異常。調試發現我們的中間層服務啓動了兩個進程: system 6074 2524 146

原创 FFmpeg入門 - 視頻播放 音視頻編解碼基礎 ffmpeg簡單入門 視頻流解析 視頻解碼 其他

系列文章: FFmpeg入門 - 視頻播放 FFmpeg入門 - rtmp推流 FFmpeg入門 - Android移植 音視頻最好從能夠直接看到東西,也更加貼近用戶的播放開始學起. 音視頻編解碼基礎 我們可以通過http、rtmp或者

原创 FFmpeg入門 - rtmp推流 rtmp服務器 推流 其他

系列文章: FFmpeg入門 - 視頻播放 FFmpeg入門 - rtmp推流 FFmpeg入門 - Android移植 上一篇博客介紹了怎樣用ffmpeg去播放視頻. 裏面用於打開視頻流的avformat_open_input函數除了

原创 FFmpeg入門 - Android移植 FFmpeg編譯與集成 OpenGLES播放FFmpeg Demo工程

系列文章: FFmpeg入門 - 視頻播放 FFmpeg入門 - rtmp推流 FFmpeg入門 - Android移植 前兩篇文章介紹瞭如何使用ffmpeg推流和拉流,這篇我們來看看怎樣將之前的代碼移植到安卓上。 FFmpeg編譯與集

原创 安卓錄製MP3(二) - LAME使用 錄音PCM 使用LAME進行MP3編碼 lame基本使用 結合JNI進行使用 DEMO代碼

上篇文章介紹了數字音頻的基礎知識,這篇文章我們來看看代碼應該怎麼寫: 錄音PCM 第一步我們先用AudioRecord錄製PCM音頻: private lateinit var buffer: ByteArray fun start(au

原创 安卓錄製MP3(一) - 數字音頻基礎 數字音頻基礎 MP3編碼

在安卓上實現錄音功能有兩種方式使用AudioRecord錄製PCM裸流,或者用MediaRecorder錄製編碼後的音頻流。但是MediaRecorder的編碼格式並不包括MP3格式: /** * Defines the audio en

原创 Bitmap內存回收機制 Android 2.3.3以前 Android 3.0~Android 7.1 Android 8.0之後

Bitmap可以說是安卓裏面最常見的內存消耗大戶了,我們開發過程中遇到的oom問題很多都是由它引發的。谷歌官方也一直在迭代它的像素內存管理策略。從 Android 2.3.3以前的分配在native上,到2.3-7.1之間的分配在java堆

原创 怎樣獲取Java泛型的具體類型 爲什麼拿不到泛型的具體類型 繼承泛型類指定泛型類型 封裝工具類

之前寫過一篇博客介紹過Java泛型的類型擦除機制,實際上Java的泛型是使用所有類的公共父類Object去實現: //錯誤,泛型的類型被擦除了,T在運行時實際上是Object,不能直接new出來 public <T> void foo(T

原创 安卓IPC機制之LocalSocket 使用方式 性能 優缺點 需要注意的地方

LocalSocket作爲安卓提供的一種IPC機制,可能應用層的同學比較陌生,我實際也是在這段時間做項目使用到才注意到它並去了解的。不過實際上framework層裏面被頻繁使用到了,例如我很久前寫的博客從源碼看安卓應用的啓動過程裏面提到其他