溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android應(yīng)用關(guān)閉的情況及識別方法是什么

發(fā)布時間:2022-06-10 10:02:46 來源:億速云 閱讀:202 作者:zzz 欄目:開發(fā)技術(shù)

這篇“Android應(yīng)用關(guān)閉的情況及識別方法是什么”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Android應(yīng)用關(guān)閉的情況及識別方法是什么”文章吧。

    引言

    探討應(yīng)用關(guān)閉問題的來由和應(yīng)用保活是關(guān)聯(lián)的,特定類型的應(yīng)用如:

    • 聊天交友軟件

    • 軌跡記錄軟件

    • 企業(yè)內(nèi)部軟件

    • 硬件搭配手機(jī)應(yīng)用檢測軟件等等

    這些應(yīng)用是需要保持長時間在后臺運行,當(dāng)應(yīng)用被關(guān)閉后,會造成數(shù)據(jù)缺失、不完整等問題。通過記錄及分析應(yīng)用關(guān)閉原因,反向得出?;罘桨甘欠裼行ВM(jìn)而改進(jìn)方案以及提示用戶減少導(dǎo)致應(yīng)用關(guān)閉的行為。

    哪些情況會導(dǎo)致應(yīng)用關(guān)閉

    一、系統(tǒng)原因

    • 手機(jī)關(guān)機(jī)

    • 手機(jī)低電量、省電模式

    • 內(nèi)存不足

    • 廠商后臺管理或通過自帶的手機(jī)管家管理行為,如

      • 華為:應(yīng)用啟動管理

      • 小米:神隱模式

      • OPPO:應(yīng)用速凍

      • VIVO:后臺高耗電

      • 三星:未監(jiān)視的應(yīng)用程序

      • 360:鎖屏清理、內(nèi)存加速

      • 魅族:后臺管理

      • 是否允許后臺運行、鎖屏清理等等

      • 場景配置

    二、用戶原因

    • 未需?;顮顟B(tài)下,用戶正常返回退出應(yīng)用

    • 手動清理掉應(yīng)用

    • 使用其他第三方手機(jī)管理軟件,關(guān)閉應(yīng)用

    三、應(yīng)用自身問題

    • 出現(xiàn)BUG導(dǎo)致應(yīng)用關(guān)閉

    識別方法

    1、應(yīng)用自身Bug問題

    要說寫代碼沒有bug,只怕誰都會說 老子/臣妾做不到,識別方式就是通過第三方SDK或自己捕獲應(yīng)用Crash,及時修復(fù)。另外也可以添加相應(yīng)的代碼在發(fā)生Crash后重啟應(yīng)用。

    2、手機(jī)關(guān)機(jī)

    大概有3種情況會關(guān)機(jī)

    • 用戶主動關(guān)機(jī)

    • 用戶設(shè)定了定時開關(guān)機(jī)任務(wù)

    • 手機(jī)系統(tǒng)自動更新,系統(tǒng)一般是默認(rèn)WLAN自動下載新版本,且開啟夜間自動安裝功能。

    識別方法:

    • AndroidManifest注冊靜態(tài)BroadcastReceiver監(jiān)聽開關(guān)機(jī)廣播事件。但是基本是無用,因為開關(guān)機(jī)廣播被手機(jī)廠商屏蔽了,需要手動設(shè)置打開開關(guān)后才能接收到。

    <receiver
        android:name=".app.receiver.ShutdownReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter android:priority="1000">
            <!-- 關(guān)機(jī)廣播 -->
            <action android:name="android.intent.action.ACTION_SHUTDOWN" />
            <!-- 手機(jī)啟動完成監(jiān)聽 -->
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    • 直接查看手機(jī)開機(jī)累計時長。在手機(jī)“設(shè)置”-“關(guān)于手機(jī)”-“狀態(tài)信息”里能查看手機(jī)的開機(jī)累計時長/已開機(jī)時間,如果時間和應(yīng)用關(guān)閉時的時間段吻合,說明是手機(jī)關(guān)機(jī)沒手動啟動應(yīng)用的緣故。

    可以看出識別開關(guān)機(jī)是比較有難度的

    3、低電量、省電模式

    手機(jī)電量低/省電模式下,系統(tǒng)會關(guān)閉非必要的應(yīng)用,以減少電量消耗。

    識別方法: 通過獲取手機(jī)電量主觀判斷是否是低電量,如應(yīng)用在電量為30還在運行,之后就沒有運行記錄了,那可能是手機(jī)觸發(fā)省電模式被關(guān)閉了。華為手機(jī)可以通過代碼判斷是否處于省電模式。

    手機(jī)電量可以通過注冊廣播監(jiān)聽或者直接通過下列代碼獲取

    public static int getBatteryLevel(Context context) {
        if(context == null){
            return -1;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            BatteryManager batteryManager = (BatteryManager) context.getSystemService(BATTERY_SERVICE);
            if (batteryManager == null) {
                return -1;
            }
            return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        } else {
            ContextWrapper wrapper = new ContextWrapper(context.getApplicationContext());
            Intent intent = wrapper.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int power = -1;
            if(intent != null)power = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            return power;
        }
    }

    華為手機(jī)判斷省電模式PowerUtils.shouldShowPowerSaveModeOption(context),0為為開省電模式,1省電模式。其他品牌手機(jī)暫無獲取方法。

    public class PowerUtils {
        //華為電源管理(設(shè)置省電的地方)
        public static Intent getPowerSaveModeIntent() {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.power.ui.HwPowerManagerActivity"));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            return intent;
        }
        /**
         * @param context
         * @return 1 省電模式
         */
        public static int shouldShowPowerSaveModeOption(Context context) {
            int a = b();
            if (a != 1) {
                return a;
            }
            try {
                ActivityInfo resolveActivityInfo = getPowerSaveModeIntent().resolveActivityInfo(context.getPackageManager(), 0);
                if (resolveActivityInfo == null || !resolveActivityInfo.exported) {
                    return -1;
                }
                return a;
            } catch (Exception e) {
                return -1;
            }
        }
        private static boolean isHuaWeiDevice() {
            String brand = Build.BRAND;
            if (brand == null) return false;
            brand = brand.toLowerCase();
            if ("huawei".contains(brand)) {
                return true;
            }
            if ("magic".contains(brand)) {
                return true;
            }
            return "honor".contains(brand);
        }
        private static int b() {
            if (Build.VERSION.SDK_INT < 24 || !isHuaWeiDevice()) {// || !LoggerFactory.getDeviceProperty().isHuaweiDevice()
                return -1;
            }
            if (i()) {
                return 1;
            }
            return 0;
        }
        private static boolean i() {
            return "false".equals(d("persist.sys.performance"));
        }
        private static Method dd;
        private static String d(String str) {
            try {
                if (dd == null) {
                    dd = Class.forName("android.os.SystemProperties").getMethod("get", new Class[]{String.class});
                }
                return (String) dd.invoke(null, new Object[]{str});
            } catch (Throwable th) {
                return null;
            }
        }
    }

    4、內(nèi)存不足

    這里會有兩種情況,一種是應(yīng)用自身申請的內(nèi)存超過系統(tǒng)給APP默認(rèn)分配的內(nèi)存大小,需要優(yōu)化應(yīng)用自身內(nèi)存占用情況,如果真的需要大內(nèi)存,就使用largeHeap增加內(nèi)存的申請量

    <application
         android:largeHeap="true">
    </application>

    另外一種情況是手機(jī)自身內(nèi)存不足,手機(jī)開了太多其他軟件,導(dǎo)致系統(tǒng)回收關(guān)閉應(yīng)用。

    識別方法: 開發(fā)調(diào)試階段可以使用Android Profiler分析應(yīng)用內(nèi)存占用情況、LeakCanary檢測是否內(nèi)存泄漏;發(fā)布版由應(yīng)用Crash日志捕獲、以及在組件中注冊內(nèi)存回調(diào)監(jiān)聽、或者使用第三方庫

    //系統(tǒng)正運行于低內(nèi)存的狀態(tài),應(yīng)用隨時可能被關(guān)閉
    public void onLowMemory() {
    }
    //預(yù)示著你設(shè)備的內(nèi)存資源已經(jīng)開始緊張,此時盡量釋放非必要內(nèi)存資源
    public void onTrimMemory(int level) {
    }

    5、用戶正常返回退出應(yīng)用

    非需后臺保活時,用戶可以按返回鍵退出應(yīng)用,這個直接在退出時做日志記錄即可

    6、廠商后臺管理與用戶手動清理應(yīng)用

    手動清理掉應(yīng)用和廠商后臺應(yīng)用管理是相關(guān)聯(lián)的。這里的手動清理指的是使用按鍵或手勢打開的【最近應(yīng)用列表】頁面,然后點單獨劃掉應(yīng)用或者點擊一鍵清理應(yīng)用的行為。Android應(yīng)用關(guān)閉的情況及識別方法是什么

    廠商后臺管理指的是

      Android應(yīng)用關(guān)閉的情況及識別方法是什么

    目前應(yīng)用想要后臺保活,只能是引導(dǎo)用戶做好相應(yīng)的【后臺運行權(quán)限設(shè)置】,而用戶是否設(shè)置正確是否打開對應(yīng)的開關(guān),沒有直接的回調(diào)方法,無法判斷。

    識別方法:

    雖然沒有直接的回調(diào)方法判斷用戶因【手動清理】應(yīng)用及因沒有設(shè)置對【后臺運行權(quán)限】而導(dǎo)致的應(yīng)用關(guān)閉,但是可以通過利用現(xiàn)有的監(jiān)聽接口及分析用戶行為間接的判斷。

    先說現(xiàn)像:

    • 如果用戶沒有設(shè)置對【后臺運行權(quán)限】,在【最近應(yīng)用列表】頁面一鍵清理時,會將應(yīng)用清理關(guān)閉

    • 如果用戶沒有設(shè)置對【后臺運行權(quán)限】,鎖屏后,過一段時間,應(yīng)用就會被自動清理關(guān)閉

    反過來,如果設(shè)置對【后臺運行權(quán)限】,一鍵清理時,應(yīng)用不會被清理關(guān)閉;鎖屏后,應(yīng)用不會被清理關(guān)閉。

    注:是否被清理掉是通過查看應(yīng)用的前臺通知服務(wù)是否存在確認(rèn)的

    根據(jù)現(xiàn)像得出判斷方法:1、監(jiān)聽手機(jī)鎖屏事件,鎖屏后,如果應(yīng)用不在運行了,說明是很可能是由于沒有設(shè)置對【后臺運行權(quán)限】導(dǎo)致的應(yīng)用關(guān)閉

    //動態(tài)注冊開鎖屏事件監(jiān)聽
    filter.addAction(Intent.ACTION_SCREEN_ON)
    filter.addAction(Intent.ACTION_SCREEN_OFF)
    filter.addAction(Intent.ACTION_USER_PRESENT)

    2、監(jiān)聽用戶打開【最近應(yīng)用列表】頁面事件,如果是打開最近應(yīng)用列表頁面后(如10s內(nèi)),應(yīng)用不在運行的,說明沒有設(shè)置對【后臺運行權(quán)限】或者是用戶主動清理關(guān)閉應(yīng)用。

    ////動態(tài)注冊手機(jī)菜單、HOME鍵事件監(jiān)聽
    filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)

    困惑行為:引導(dǎo)用戶設(shè)置對后臺運行權(quán)限是相當(dāng)考驗產(chǎn)品文檔及客服人員事情,有的用戶其實已經(jīng)設(shè)置對后臺運行權(quán)限了,但是應(yīng)用還是關(guān)閉了,原因是用戶覺得已經(jīng)設(shè)置了【自啟動】【允許后臺運行】應(yīng)用就會一直在后臺運行,轉(zhuǎn)為做些主動關(guān)閉應(yīng)用的操作,如:在應(yīng)用信息里點【強(qiáng)行停止】【結(jié)束運行】及本文提到的其他導(dǎo)致應(yīng)用關(guān)閉的行為而沒有重新手動再次打開應(yīng)用。

    其實做各種【后臺運行權(quán)限】設(shè)置也只是告訴系統(tǒng)不要去清理關(guān)閉應(yīng)用,讓應(yīng)用在后臺運行,但是如果用戶主動去關(guān)閉應(yīng)用,系統(tǒng)還是會以用戶的想法為準(zhǔn)。用戶不想讓應(yīng)用運行,那應(yīng)用就不能運行。

    7、其他原因

    使用第三方應(yīng)用管理軟件、更改應(yīng)用權(quán)限、安裝新版本應(yīng)用、卸載應(yīng)用等等

    以上就是關(guān)于“Android應(yīng)用關(guān)閉的情況及識別方法是什么”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI