簡體   English   中英

當手機處於睡眠模式或長時間隱藏應用時,Android后台服務的運行速度較慢

[英]Android background service works slower when phone in sleep mode or app hidden for a some long time

我編寫了一個Android本機應用程序,它會定期請求LatLng坐標。

因此,我有運行UI的MainActivity類。 在這里,我使用Intent啟動后台服務:

public class MainActivity extends AppCompatActivity {

    // here are defined required methods like OnCreate() etc.

    Intent locTaskIntent = new Intent(this, LocationsTaskService.class);
    startService(locTaskIntent);

    // ...
}

onStartCommand()啟動的Service定期調度異步任務:

public class LocationsTaskService extends Service {
public int onStartCommand(Intent intent, int flags, int startid) {
    final Handler handler = new Handler();
    Timer taskTimer = new Timer();
    TimerTask asyncTask = new TimerTask() {
        @Override
        public void run () {
            handler.post(new Runnable() {
                public void run () {
                    LocationProcessor LocationProcessor = new LocationProcessor(mContext, ++counter);
                    LocationProcessor.startRoutine();
                }
            });
        }
    };
    taskTimer.schedule(asyncTask, 0, RConstants.locUpdateInterval);
    return super.onStartCommand(intent, flags, startid);
}

LocationProcessor類的startRoutine()方法為android os執行操作以請求位置,然后等待在LocationListener中實現的回調方法中的答案或通過超時取消搜索:

private class LocationProcessor {

    // ....

    LocationProcessor(Context context, int sessionId) {
        mLocManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        mSessionId = sessionId;
    }

    public void startRoutine() {
        // The CountDownTimer is used to break locations search by timeout
        cdTimer = new CountDownTimer(RConstants.locUpdateTimeoutUsed, RConstants.locUpdateTimeoutUsed ) {
                @Override
                public void onFinish() {
                    // cancel updates listening
                    mLocManager.removeUpdates(locationListener);
                    mLocManager = null;
                }
            }.start();
        // requesting for location updates
        mLocManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    MIN_TIME_BW_UPDTS,
                    MIN_DIST_CHANGE_FOR_UPDTS,
                    locationListener
            );
    }

private LocationListener locationListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        cdTimer.cancel();
        cdTimer = null;
        mLocManager.removeUpdates(locationListener);
        mLocManager = null;
    }
}

清單文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.location.devsname.appname">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:launchMode="singleTask">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".LocationsTaskService">

        </service>

    </application>

</manifest>

問題是:

  1. 在手機長時間入睡和/或隱藏應用程序之前,應用程序可以正常工作。

喚醒電話時,我可以看到以下圖片(紅色標記與狀態有關,即手機處於休眠狀態;對於相反的狀態,綠色標記與及時接收消息有關):

應用的屏幕截圖

  1. 當我在電話中啟動一些消耗內存的應用程序時(它只有512 MB RAM),我收到來自系統的消息,例如:“抱歉,..應用程序名稱..已停止”。 似乎OS傾向於為新的加載應用程序釋放內存,殺死了舊進程- 這是我的猜測 我如何強行要求系統維護其運行?

對於第二點,我相信從您的onStartCommand返回START_STICKY可以onStartCommand

從文檔中

詮釋START_STICKY

從onStartCommand(Intent,int,int)返回的常量:如果此服務的進程在啟動時被殺死(從onStartCommand(Intent,int,int)返回之后),則將其保留為啟動狀態,但不保留此狀態傳達了意圖。 稍后,系統將嘗試重新創建服務。 因為它處於啟動狀態,所以它將保證在創建新服務實例后調用onStartCommand(Intent,int,int); 如果沒有任何待處理的啟動命令要傳遞給服務,則將使用空意圖對象調用該命令,因此您必須注意進行檢查。

對於在任意時間段內將明確啟動和停止運行的事物(例如執行背景音樂播放的服務),此模式有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM