I'm trying to make an android app that launches a service which runs in the background while the app is open, and doesn't die when the app is closed. However, my service does seem to die upon exit (or at some point, anyhow), because when I restart the app my check to see if the service is running is false. My code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ToggleButton enableButton;
private boolean isRunning;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
enableButton = findViewById(R.id.enableButton);
setRunning(MyService.running());
enableButton.setChecked(isRunning);
enableButton.setEnabled(true);
enableButton.setClickable(true);
}
private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
public void onToggleEnable(View view) {
boolean enabled = enableButton.isChecked();
Intent intent = new Intent(this, MyService.class);
if (enabled) startService(intent);
else stopService(intent);
setRunning(enabled);
}
}
MyService.java
public class MyService extends Service {
private static boolean running = false;
public static boolean running() {
return running;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
running = true;
return START_STICKY;
}
@Override
public void onDestroy() {
running = false;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.chuckles.iscream">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="false" />
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ToggleButton
android:id="@+id/enableButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:onClick="onToggleEnable"
android:textOff="@string/screamOff"
android:textOn="@string/screamOn"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</ScrollView>
strings.xml
<resources>
<string name="app_name">iScream</string>
<string name="screamOn">Disable iScream</string>
<string name="screamOff">Enable iScream</string>
</resources>
Your Service
may killed by the System. From official doc:
The Android system force-stops a service only when memory is low and it must recover system resources for the activity that has user focus. If the service is bound to an activity that has user focus, it's less likely to be killed; if the service is declared to run in the foreground, it's rarely killed.
So if you want to keep running your Service
while your app is not open then your Service
should be declared to run in the foreground . For this you have to call startForeground(ONGOING_NOTIFICATION_ID, notification);
As stated here:
https://developer.android.com/guide/components/services.html
Caution: A service runs in the main thread of its hosting process; the service does not create its own thread and does not run in a separate process unless you specify otherwise.
Use an IntentService instead if you wish it to run in a seperate thread
https://developer.android.com/guide/components/services.html#ExtendingIntentService
The IntentService class does the following:
It creates a default worker thread that executes all of the intents that are delivered to onStartCommand(), separate from your application's main thread.
在清单文件中的服务标签中,只需添加:
android:process=":externalProcess"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.