首頁>技術>

前言

相信很多工作幾年的Android程式設計師對Android的API都比較熟,呼叫起來也毫不含糊,實在不常用的類查一下API文件也能輕鬆搞定。

但是你們有沒有遇到過這樣的問題,客戶或者老闆提了一個需求,而Android自己的API是不支援這個功能的?我就遇到過這樣的問題,商顯裝置為了省電節約成本, 會在半夜沒人的時候自己關機,到了早上6點又自啟,然而Andorid系統從斷電到自啟是需要底層適配的,再或者就是要同步板子上的RTC時鐘(硬體時鐘,類似於電腦主機板上關機後依然記錄時間的一個模組)的時間

這一類問題,都是要先修改Android原始碼做到底層適配,然後匯入自編譯framework.jar包才能得以實現的,下面以同步RTC時鐘為例:

開始

可以看到我們在frameworks下做了一些改動,透過新增jni呼叫底層的一些cpp中的方法,然後在AlarmManager.java類中新增定義,封裝自己的setRtcTime方法。

改動完畢之後,進行編譯燒錄,這樣我們機器的Android系統裡的AlarmManager類裡新增了一個叫做setRtcTime的方法,名字隨便你起,也就是相當於多了一個全新的API。那我們在這個機器的系統上跑的apk可以直接呼叫麼?我們試試。

新建一個專案,叫FrameWorkApp,封裝一個工具類NewAlarmHelper,可以呼叫我們的setRtcTime方法:

public class MainActivity extends AppCompatActivity {    private Button btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn = findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Calendar calendar = Calendar.getInstance();                calendar.set(2020, 11, 12, 12, 12, 11);                NewAlarmHelper.setRtcTime(MainActivity.this,calendar.getTimeInMillis());            }        });    }}

好了,就是這樣,我們編譯生成apk,看一下結果如何。

Oh no,編譯都過不了,直接告訴你說沒有這個方法。這就是今天的主題所要說的東西了,你雖然在系統層已經做了適配,但是AndroidStudio它的API還是根據google預設的API來進行編譯,google怎麼會知道你自己要新增什麼方法。

那麼我們怎麼辦才能正常生成apk呢? 首先找到你的專案原始碼,我的這個專案原始碼是amlogic平臺,Android 9.0系統的,所以這篇部落格同樣適用於Android高版本這類問題的解決。

我們找到out\target\common\obj\JAVA_LIBRARIES\framework_intermediates目錄下的classes.jar檔案,這個檔案就是我們要的framework.jar包。

這個jar包才是可以供AS使用的,它有自己一定的大小,我這裡是21M左右,因平臺而異。而如果你天真的直接在out目錄下搜尋framework.jar也是可以搜到的。

但是這些jar包都是不起作用的,我剛開始在網上搜一些資料,大部分沒有點名這個問題,導致自己也走了很多的彎路,這些jar包都是幾kb左右,所以大家一定要找對檔案(一定是有大小的,而不是幾kb),不要走這樣的彎路。

既然我們找到了對應的jar包,那我們就把它重新命名為framework.jar,意思是這個jar包是framework相關的。

因為你這個專案可能不止一個人維護,或者說萬一你離職了,交接時沒有這麼細節的說明這個問題,那麼別的程式設計師看到這個名叫classes.jar的時候會一臉蒙圈。

說到導包,有人會說了,這個我知道,複製貼上到lib目錄下,然後Add As Library就可以了,下面的你就不用講了。

其實不然,這個和之前的jar包匯入有很大區別。那麼接下來,我就按部就班的教大家如何匯入這個我們自己編譯的framework.jar。

首先,我們把改好名字的framework.jar檔案複製貼上到lib目錄下,^_^(哈哈)。

然後,重點來了,不用右鍵選Add As Library,而是直接去開啟app目錄下的build.gradle檔案。

最後,在Project的build.gradle的allprojects中,將我們自己編譯的framework.jar包設定為優先於系統包,然後Sync Porject 。

// 設定framework.jar包優先系統包    gradle.projectsEvaluated {        tasks.withType(JavaCompile) {            options.compilerArgs.add('-Xbootclasspath/p:app/libs/framework.jar')        }    }

到這裡三步,我們已經成功把大象裝進了冰箱,在AS中匯入了自己編譯的framework.jar包,空口無憑,我們試試能不能編譯生成apk包吧。

系統時間已經修改,再看下硬體時鐘。

硬體時鐘2020-12-12 04:12,怎麼不是12:12呢 ???哈哈,因為硬體時鐘記錄的時間為格林威治標準時間,我們一般用的都是東八區北京時間,所以要比格林威治標準時間多加8個小時。

所以我們系統時間和硬體時鐘全部都設定成功!

最後

最後,在這裡我也分享一份乾貨,由大佬收錄整理的 Android學習PDF+架構影片+原始碼筆記,還有高階架構技術進階腦圖、Android開發面試專題資料,高階進階架構資料幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習。

12
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 淺談企業資料目錄架構及部署方式