<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    1、引言

    對(duì)于移動(dòng)端IM應(yīng)用和消息推送應(yīng)用的開發(fā)者來說,Android后臺(tái)保活這件事是再熟悉不過了。

    自從Android P(即Android 8.0)出現(xiàn)以后,Android已經(jīng)從系統(tǒng)層面將后臺(tái)保活這條路給堵死了(詳見:《Android P正式版即將到來:后臺(tái)應(yīng)用保活、消息推送的真正噩夢(mèng)》),曾今那些層出不窮的保活黑科技能用的也越來越少了(詳見:《全面盤點(diǎn)當(dāng)前Android后臺(tái)保活方案的真實(shí)運(yùn)行效果(截止2019年前)》。雖然可以自已對(duì)接廠商的ROOM級(jí)推送通道,但一方面各廠商的推送接口都不一樣(而且同一廠商不同的系統(tǒng)版本間也存在推送接口的兼容性問題),很不方便。另一方面要一家家引入各自的推送服務(wù)SDK包會(huì)讓APP變的很大,這讓APP的下載變的很不友好。

    總之,Android應(yīng)用的后臺(tái)保活在某些場(chǎng)景下,還是有持續(xù)的需求。除了之前那些耳熟能詳?shù)谋;詈诳萍家酝猓贏ndroid 9.0(甚至Android 10)時(shí)代,我們還有哪些保活方法可以用?那么,請(qǐng)跟著本文作者的思路,看看更優(yōu)雅的后臺(tái)保活實(shí)現(xiàn)方法吧。

    (本文同步發(fā)布于:http://www.52im.net/thread-2881-1-1.html

     

    2、關(guān)于作者

    網(wǎng)名NanBox:畢業(yè)于華中科技大學(xué),現(xiàn)為"悅跑圈APP”高級(jí)Android開發(fā)工程師。主要負(fù)責(zé)公司 Android 項(xiàng)目,核心模塊的開發(fā)。涉及 GPS 定位、地圖、圖片編輯等功能。獨(dú)立開發(fā)了手表應(yīng)用項(xiàng)目。 在項(xiàng)目中應(yīng)入了 Flutter 跨平臺(tái)開發(fā)技術(shù),實(shí)現(xiàn)了原生和 Flutter 的混合開發(fā)。

    本文作者樂于分享,平時(shí)會(huì)寫技術(shù)文章并分享在多個(gè)平臺(tái),是掘金專欄作者的一員,文章總閱讀量超過 10 萬(wàn)。在 GitHub 上有多個(gè)開源項(xiàng)目,多次在團(tuán)隊(duì)內(nèi)部進(jìn)行技術(shù)分享。是 Android 和 Flutter 官方中文文檔譯者。

    3、相關(guān)文章

    如果你想詳細(xì)了解目前Android平臺(tái)上后臺(tái)保活技術(shù)的挑戰(zhàn),請(qǐng)閱讀:

    Android P正式版即將到來:后臺(tái)應(yīng)用保活、消息推送的真正噩夢(mèng)》。

    如果你想回顧那些曾今出現(xiàn)的Android保活黑科技,以下文章值得好好讀讀:

    全面盤點(diǎn)當(dāng)前Android后臺(tái)保活方案的真實(shí)運(yùn)行效果(截止2019年前)

    應(yīng)用保活終極總結(jié)(一):Android6.0以下的雙進(jìn)程守護(hù)保活實(shí)踐

    應(yīng)用保活終極總結(jié)(二):Android6.0及以上的保活實(shí)踐(進(jìn)程防殺篇)

    應(yīng)用保活終極總結(jié)(三):Android6.0及以上的保活實(shí)踐(被殺復(fù)活篇)

    Android進(jìn)程保活詳解:一篇文章解決你的所有疑問

    Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳保活、遇到的問題等

    深入的聊聊Android消息推送這件小事

    為何基于TCP協(xié)議的移動(dòng)端IM仍然需要心跳保活機(jī)制?

    微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(進(jìn)程保活篇)

    融云技術(shù)分享:融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路保活技術(shù)實(shí)踐

    4、Android保活現(xiàn)狀

    我們知道,Android 系統(tǒng)會(huì)存在殺后臺(tái)進(jìn)程的情況,并且隨著系統(tǒng)版本的更新,殺進(jìn)程的力度還有越來越大的趨勢(shì)(見:《Android P正式版即將到來:后臺(tái)應(yīng)用保活、消息推送的真正噩夢(mèng)》)。

    系統(tǒng)這種做法本身出發(fā)點(diǎn)是好的,因?yàn)榭梢怨?jié)省內(nèi)存,降低功耗,也避免了一些流氓行為。

    但有一部分應(yīng)用,應(yīng)用本身的使用場(chǎng)景就需要在后臺(tái)運(yùn)行,用戶也是愿意讓它在后臺(tái)運(yùn)行的,比如跑步類應(yīng)用、一些懶得對(duì)接廠商推送通道的IM應(yīng)用、消息推送資訊類應(yīng)用等。

    一方面流氓軟件用各種流氓手段進(jìn)行保活,另一方面系統(tǒng)加大殺后臺(tái)的力度,導(dǎo)致我們一些真正需要在后臺(tái)運(yùn)行的應(yīng)用被誤殺,苦不堪言。

    5、優(yōu)雅的保活?

    為了做到保活,出現(xiàn)了不少「黑科技」,比如 1 個(gè)像素的 Activity,播放無(wú)聲音頻,雙進(jìn)程互相守護(hù)等(可以讀讀這個(gè)系列:《應(yīng)用保活終極總結(jié)(一):Android6.0以下的雙進(jìn)程守護(hù)保活實(shí)踐》、《應(yīng)用保活終極總結(jié)(二):Android6.0及以上的保活實(shí)踐(進(jìn)程防殺篇)》、《應(yīng)用保活終極總結(jié)(三):Android6.0及以上的保活實(shí)踐(被殺復(fù)活篇)》)。

    這些做法可以說是很流氓了,甚至破壞了 Android 的生態(tài),好在隨著 Android 系統(tǒng)版本的更新,這些非常規(guī)的保活手段很多都已失效了。

    對(duì)于那些確實(shí)需要在后臺(tái)運(yùn)行的應(yīng)用,我們?nèi)绾巫龅絻?yōu)雅的保活呢?

    6、加入后臺(tái)運(yùn)行白名單,可以優(yōu)雅的實(shí)現(xiàn)保活

    從 Android 6.0 開始,系統(tǒng)為了省電增加了休眠模式,系統(tǒng)待機(jī)一段時(shí)間后,會(huì)殺死后臺(tái)正在運(yùn)行的進(jìn)程。但系統(tǒng)會(huì)有一個(gè)后臺(tái)運(yùn)行白名單,白名單里的應(yīng)用將不會(huì)受到影響,在原生系統(tǒng)下,通過:「設(shè)置」 - 「電池」 - 「電池優(yōu)化」 - 「未優(yōu)化應(yīng)用」,可以看到這個(gè)白名單。

    通常會(huì)看到下面這兩位: 

    下次被產(chǎn)品說「 XXX 都可以保活,為什么我們不行!」的時(shí)候,你就知道怎么懟回去了。大廠通過和手機(jī)廠商的合作,將自己的應(yīng)用默認(rèn)加入到白名單中。如果你在一個(gè)能談成這種合作的大廠,也就不用往下看了。

    好在系統(tǒng)還沒有拋棄我們,允許我們申請(qǐng)把應(yīng)用加入白名單。

    首先,在 AndroidManifest.xml 文件中配置一下權(quán)限:

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

    可以通過以下方法,判斷我們的應(yīng)用是否在白名單中:

    @RequiresApi(api = Build.VERSION_CODES.M)

    private boolean isIgnoringBatteryOptimizations() {

        boolean isIgnoring = false;

        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);

        if(powerManager != null) {

            isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());

        }

        return isIgnoring;

    }

    如果不在白名單中,可以通過以下代碼申請(qǐng)加入白名單:

    @RequiresApi(api = Build.VERSION_CODES.M)

    public void requestIgnoreBatteryOptimizations() {

        try{

            Intent intent = newIntent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);

            intent.setData(Uri.parse("package:"+ getPackageName()));

            startActivity(intent);

        } catch(Exception e) {

            e.printStackTrace();

        }

    }

    申請(qǐng)時(shí),應(yīng)用上會(huì)出現(xiàn)這樣一個(gè)窗口:

    可以看到,這個(gè)系統(tǒng)彈窗會(huì)有影響電池續(xù)航的提醒,所以如果想讓用戶點(diǎn)允許,必須要有相關(guān)的說明。如果要判斷用戶是否點(diǎn)擊了允許,可以在申請(qǐng)的時(shí)候調(diào)用 startActivityForResult,在 onActivityResult 里再判斷一次是否在白名單中。

    7、加入后臺(tái)運(yùn)行白名單的多廠商適配方法

    7.1 基本說明

    Android 開發(fā)的一個(gè)難點(diǎn)在于,各大手機(jī)廠商對(duì)原生系統(tǒng)進(jìn)行了不同的定制,導(dǎo)致我們需要進(jìn)行不同的適配,后臺(tái)管理就是一個(gè)很好的體現(xiàn)。幾乎各個(gè)廠商都有自己的后臺(tái)管理,就算應(yīng)用加入了后臺(tái)運(yùn)行白名單,仍然可能會(huì)被廠商自己的后臺(tái)管理干掉。

    如果能把應(yīng)用加入廠商系統(tǒng)的后臺(tái)管理白名單,可以進(jìn)一步降低進(jìn)程被殺的概率。不同的廠商在不同的地方進(jìn)行設(shè)置,一般是在各自的「手機(jī)管家」,但更難的是,就算同一個(gè)廠商的系統(tǒng),不同的版本也可能是在不同地方設(shè)置。

    最理想的做法是,我們根據(jù)不同手機(jī),甚至是不同的系統(tǒng)版本,給用戶呈現(xiàn)一個(gè)圖文操作步驟,并且提供一個(gè)按鈕,直接跳轉(zhuǎn)到指定頁(yè)面進(jìn)行設(shè)置。但需要對(duì)每個(gè)廠商每個(gè)版本進(jìn)行適配,工作量是比較大的。我使用真機(jī)測(cè)試了大部分主流 Android 廠商的手機(jī)后,整理出了部分手機(jī)的相關(guān)資料。

    首先我們可以定義這樣兩個(gè)方法:

    /**

     * 跳轉(zhuǎn)到指定應(yīng)用的首頁(yè)

     */

    private void showActivity(@NonNull String packageName) {

        Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);

        startActivity(intent);

    }

     

    /**

     * 跳轉(zhuǎn)到指定應(yīng)用的指定頁(yè)面

     */

    private void showActivity(@NonNull String packageName, @NonNull String activityDir) {

        Intent intent = new Intent();

        intent.setComponent(newComponentName(packageName, activityDir));

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        startActivity(intent);

    }

    以下是部分手機(jī)的廠商判斷,跳轉(zhuǎn)方法及對(duì)應(yīng)設(shè)置步驟,跳轉(zhuǎn)方法不保證在所有版本上都能成功跳轉(zhuǎn),都需要加 try catch。

    7.2 華為

    廠商判斷:

    public boolean isHuawei() {

        if(Build.BRAND == null) {

            return false;

        } else{

            return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");

        }

    }

    跳轉(zhuǎn)華為手機(jī)管家的啟動(dòng)管理頁(yè):

    private void goHuaweiSetting() {

        try{

            showActivity("com.huawei.systemmanager",

                "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");

        } catch(Exception e) {

            showActivity("com.huawei.systemmanager",

                "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");

        }

    }

    操作步驟:應(yīng)用啟動(dòng)管理 -> 關(guān)閉應(yīng)用開關(guān) -> 打開允許自啟動(dòng)

    7.3 小米

    廠商判斷:

    public static boolean isXiaomi() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("xiaomi");

    }

    跳轉(zhuǎn)小米安全中心的自啟動(dòng)管理頁(yè)面:

    private void goXiaomiSetting() {

        showActivity("com.miui.securitycenter",

            "com.miui.permcenter.autostart.AutoStartManagementActivity");

    }

    操作步驟:授權(quán)管理 -> 自啟動(dòng)管理 -> 允許應(yīng)用自啟動(dòng)

    7.4 OPPO

    廠商判斷:

    public static boolean isOPPO() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("oppo");

    }

    跳轉(zhuǎn) OPPO 手機(jī)管家:

    private void goOPPOSetting() {

        try{

            showActivity("com.coloros.phonemanager");

        } catch(Exception e1) {

            try{

                showActivity("com.oppo.safe");

            } catch(Exception e2) {

                try{

                    showActivity("com.coloros.oppoguardelf");

                } catch(Exception e3) {

                    showActivity("com.coloros.safecenter");

                }

            }

        }

    }

    操作步驟:權(quán)限隱私 -> 自啟動(dòng)管理 -> 允許應(yīng)用自啟動(dòng)

    7.5 VIVO

    廠商判斷:

    public static boolean isVIVO() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("vivo");

    }

    跳轉(zhuǎn) VIVO 手機(jī)管家:

    private void goVIVOSetting() {

        showActivity("com.iqoo.secure");

    }

    操作步驟:權(quán)限管理 -> 自啟動(dòng) -> 允許應(yīng)用自啟動(dòng)

    7.6 魅族

    廠商判斷:

    public static boolean isMeizu() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("meizu");

    }

    跳轉(zhuǎn)魅族手機(jī)管家:

    private void goMeizuSetting() {

        showActivity("com.meizu.safe");

    }

    操作步驟:權(quán)限管理 -> 后臺(tái)管理 -> 點(diǎn)擊應(yīng)用 -> 允許后臺(tái)運(yùn)行

    7.7 三星

    廠商判斷:

    public static boolean isSamsung() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("samsung");

    }

    跳轉(zhuǎn)三星智能管理器:

    private void goSamsungSetting() {

        try{

            showActivity("com.samsung.android.sm_cn");

        } catch(Exception e) {

            showActivity("com.samsung.android.sm");

        }

    }

    操作步驟:自動(dòng)運(yùn)行應(yīng)用程序 -> 打開應(yīng)用開關(guān) -> 電池管理 -> 未監(jiān)視的應(yīng)用程序 -> 添加應(yīng)用

    7.8 樂視

    廠商判斷:

    public static boolean isLeTV() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("letv");

    }

    跳轉(zhuǎn)樂視手機(jī)管家:

    private void goLetvSetting() {

        showActivity("com.letv.android.letvsafe",

            "com.letv.android.letvsafe.AutobootManageActivity");

    }

    操作步驟:自啟動(dòng)管理 -> 允許應(yīng)用自啟動(dòng)

    7.9 錘子

    廠商判斷:

    public static boolean isSmartisan() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("smartisan");

    }

    跳轉(zhuǎn)手機(jī)管理:

    private void goSmartisanSetting() {

        showActivity("com.smartisanos.security");

    }

    操作步驟:權(quán)限管理 -> 自啟動(dòng)權(quán)限管理 -> 點(diǎn)擊應(yīng)用 -> 允許被系統(tǒng)啟動(dòng)。

    8、友商致敬?

    在之前做的跑步應(yīng)用中,我在設(shè)置里增加了一個(gè)權(quán)限設(shè)置頁(yè)面,將上面提到的設(shè)置放在這里面。

    最近發(fā)現(xiàn)友商某咚也跟進(jìn)了,圖 1 是我們做的,圖 2 是某咚做的: 

    某咚從設(shè)計(jì)、從我寫的不夠好的文案,甚至是我從十幾臺(tái)手機(jī)上一張一張截下來的圖,進(jìn)行了全方位的致敬。感謝某咚的認(rèn)可,但最近在某個(gè)發(fā)布會(huì)上聽到這么一句話:在致敬的同時(shí),能不能說一句謝謝?

    某咚的致敬,一方面說明了目前確實(shí)存在進(jìn)程容易被殺,保活難度大的問題,另一方面也說明了這種引導(dǎo)用戶進(jìn)行白名單設(shè)置的手段是有效的。

    附錄:更多相關(guān)技術(shù)文章

    應(yīng)用保活終極總結(jié)(一):Android6.0以下的雙進(jìn)程守護(hù)保活實(shí)踐

    應(yīng)用保活終極總結(jié)(二):Android6.0及以上的保活實(shí)踐(進(jìn)程防殺篇)

    應(yīng)用保活終極總結(jié)(三):Android6.0及以上的保活實(shí)踐(被殺復(fù)活篇)

    Android進(jìn)程保活詳解:一篇文章解決你的所有疑問

    Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳保活、遇到的問題等

    深入的聊聊Android消息推送這件小事

    為何基于TCP協(xié)議的移動(dòng)端IM仍然需要心跳保活機(jī)制?

    微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(進(jìn)程保活篇)

    微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(網(wǎng)絡(luò)保活篇)

    移動(dòng)端IM實(shí)踐:實(shí)現(xiàn)Android版微信的智能心跳機(jī)制

    移動(dòng)端IM實(shí)踐:WhatsApp、Line、微信的心跳策略分析

    Android P正式版即將到來:后臺(tái)應(yīng)用保活、消息推送的真正噩夢(mèng)

    全面盤點(diǎn)當(dāng)前Android后臺(tái)保活方案的真實(shí)運(yùn)行效果(截止2019年前)

    一文讀懂即時(shí)通訊應(yīng)用中的網(wǎng)絡(luò)心跳包機(jī)制:作用、原理、實(shí)現(xiàn)思路等

    融云技術(shù)分享:融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路保活技術(shù)實(shí)踐

    正確理解IM長(zhǎng)連接的心跳及重連機(jī)制,并動(dòng)手實(shí)現(xiàn)(有完整IM源碼)

    2020年了,Android后臺(tái)保活還有戲嗎?看我如何優(yōu)雅的實(shí)現(xiàn)!

    >> 更多同類文章 ……

    (本文同步發(fā)布于:http://www.52im.net/thread-2881-1-1.html



    作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時(shí)通訊開發(fā)交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 免费中文字幕在线| 亚洲hairy多毛pics大全| 久久综合亚洲色hezyo| 久久免费看黄a级毛片| 久久久无码精品亚洲日韩蜜臀浪潮| 成人人免费夜夜视频观看| 免费a级毛片在线观看| 国产精品久久久久久亚洲小说| 日韩激情淫片免费看| 久久精品国产精品亚洲艾草网| 亚洲免费观看视频| 亚洲成a人片在线观看中文动漫| 无码成A毛片免费| 亚洲精品综合久久中文字幕| 成人黄色免费网址| 国产成人精品日本亚洲专区6| 亚洲免费综合色在线视频| 亚洲av片一区二区三区| 亚洲av永久无码精品漫画| 午夜精品免费在线观看| 亚洲欧洲在线播放| 免费视频成人国产精品网站| 亚洲国产精品人久久电影| 女人18一级毛片免费观看| 亚洲精品乱码久久久久蜜桃| 亚洲av日韩av欧v在线天堂| 中文在线观看永久免费| 亚洲精品午夜久久久伊人| 永久免费bbbbbb视频| 无码日韩人妻AV一区免费l| 亚洲第一精品福利| 国产无遮挡吃胸膜奶免费看| 国产精品亚洲五月天高清| 国产av天堂亚洲国产av天堂| 无码人妻精品中文字幕免费东京热| 亚洲AV无码一区二区一二区| 亚洲精品成人网站在线观看| 成人网站免费观看| CAOPORN国产精品免费视频| 亚洲手机中文字幕| 中文亚洲成a人片在线观看|