Article Directory
-
- In-depth Analysis of Android Service (End)
- 1. Service Lifecycle Management
- 2. Service lifecycle approach
-
- 2.1 onCreate()
- 2.2 onStartCommand(Intent intent, int flags, int startId)
- 2.3 onBind(Intent intent)
- 2.4 onUnbind(Intent intent)
- 2.5 onRebind(Intent intent)
- 2.6 onDestroy()
- 3. Service Restart Policy
- 4. Use Service for foreground tasks
- 5. Implementing the Foreground Service Example
-
- 5.1 Create Front Office Service
- 5.2 Start the front desk service
- 6. Service Optimization and Debugging
-
- 6.1Replace traditional Service with JobS scheduler
- 6.2 Use WorkManager to handle background tasks
- 6.3 Commissioning and monitoring
- 7. Summary of sample code
-
- 7.1 Server code (Messenger)
- 7.2 Client Code (Messenger)
- 7.3 Server Code (AIDL)
- 7.4 Client Code (AIDL)
- 8. Sum up
In-depth Analysis of Android Service (End)
1. Service Lifecycle Management
Service
Lifecycle management is key to ensuring that Service
resources can be started, run, stopped, and cleaned up correctly. An understood Service
lifecycle approach can help developers better manage and optimize Service
.
2. Service lifecycle approach
The Service
main life cycle methods of include:
onCreate()
onStartCommand(Intent intent, int flags, int startId)
onBind(Intent intent)
onUnbind(Intent intent)
onRebind(Intent intent)
onDestroy()
2.1 onCreate()
Called when Service
is created. Any necessary resources are typically initialized here.
@Override
public void onCreate() {
super.onCreate();
// Initialize resources,Such as thread pool、Database connection, etc.
}
2.2 onStartCommand(Intent intent, int flags, int startId)
Called each time startService()
the method is started Service
. This method is the main entry point to handle the actual business logic. The return value determines how the system restarts the service after it is killed due to insufficient memory.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Handle business logic,Such as downloading files、Play music etc.
return START_STICKY; // START_NOT_STICKY, START_REDELIVER_INTENT, or START_STICKY_COMPATIBILITY
}
2.3 onBind(Intent intent)
Called when the client is Service
bound. Returns an IBinder
object for communicating with the client.
@Override
public IBinder onBind(Intent intent) {
// Return communication interface
return binder;
}
2.4 onUnbind(Intent intent)
Called when all clients are unbound. This is where binding-related resources are typically cleaned up.
@Override
public boolean onUnbind(Intent intent) {
// Clean up binding related resources
return super.onUnbind(intent);
}
2.5 onRebind(Intent intent)
Called when the new client is bound Service
again after the previous call onUnbind()
.
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
2.6 onDestroy()
Called before Service
being destroyed. Usually clean up all resources here.
@Override
public void onDestroy() {
super.onDestroy();
// Release resources
}
3. Service Restart Policy
The return value of the onStartCommand
method determines how the system restarts it after it is killed Service
due to insufficient system memory:
START_STICKY
: The service will be restarted automatically after being stopped by the system. The Intent is not preserved, meaning that the data is not preserved, but the service continues to run.START_NOT_STICKY
: The service will not restart automatically after being stopped by the system unless there is a new Intent.START_REDELIVER_INTENT
: After the service is terminated by the system, it will be restarted automatically and the last Intent will be retransmitted.START_STICKY_COMPATIBILITY
: Similar toSTART_STICKY
, but for compatibility with lower versions.
4. Use Service for foreground tasks
To ensure that Service
it is not terminated by the system when running in the background, it can be Service
promoted to a foreground service. This is done by calling startForeground()
the method and providing a persistent notification.
5. Implementing the Foreground Service Example
5.1 Create Front Office Service
public class ForegroundService extends Service {
@Override
public void onCreate() {
super.onCreate();
Notification notification = createNotification();
startForeground(1, notification);
}
private Notification createNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "foreground_service_channel";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setContentTitle("Foreground Service")
.setContentText("Service is running in the foreground")
.setSmallIcon(R.drawable.ic_service_icon);
return builder.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Handle business logic
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
5.2 Start the front desk service
To start the foreground service in Activity
:
Intent intent = new Intent(this, ForegroundService.class);
startService(intent);
6. Service Optimization and Debugging
To optimize Service
the performance and reliability of the, the following methods can be used:
6.1Replace traditional Service with JobS scheduler
Recommended JobScheduler
for tasks that need to run under specific conditions. It optimizes the execution time of the task based on system resources and conditions.
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(this, MyJobService.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(true)
.build();
jobScheduler.schedule(jobInfo);
6.2 Use WorkManager to handle background tasks
A modern task scheduling mechanism is WorkManager
provided, which is suitable for the scenario where task execution needs to be guaranteed. It can automatically handle retries and constraints on tasks.
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(new Constraints.Builder().setRequiresCharging(true).build())
.build();
WorkManager.getInstance(this).enqueue(workRequest);
6.3 Commissioning and monitoring
Use to StrictMode
detect potential performance problems, such as disk reads and writes and network access:
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
}
Utilize Android Studio’s Profiler tool to monitor Service
CPU, memory, and network usage to identify and resolve performance bottlenecks.
7. Summary of sample code
7.1 Server code (Messenger)
public class MessengerService extends Service {
static final int MSG_SAY_HELLO = 1;
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "Hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger messenger = new Messenger(new IncomingHandler());
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
7.2 Client Code (Messenger)
public class MainActivity extends AppCompatActivity {
Messenger messenger = null;
boolean isBound = false;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger = new Messenger(service);
isBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
messenger = null;
isBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
Button sendButton = findViewById(R.id.sendButton);
sendButton.setOnClickListener(v -> {
if (isBound) {
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(connection);
isBound = false;
}
}
}
7.3 Server Code (AIDL)
public class MyAidlService extends Service {
private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
@Override
public int add(int a, int b) {
return a + b;
}
};
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
7.4 Client Code (AIDL)
public class MainActivity extends AppCompatActivity {
IMyAidlInterface myAidlService = null;
boolean isBound = false;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAidlService = IMyAidlInterface.Stub.asInterface(service);
isBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
myAidlService = null;
isBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MyAidlService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
Button addButton = findViewById(R.id.addButton);
addButton.setOnClickListener(v -> {
if (isBound) {
try {
int result = myAidlService.add(5, 3);
Toast.makeText(MainActivity.this, "Result: " + result, Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(connection);
isBound = false;
}
}
}
8. Sum up
Reasonable design and optimization of Android Service
can ensure that applications run efficiently and stably in the background and provide a good user experience. It is hoped that this series of articles can help developers better understand Service
the working mechanism and optimization strategies, and provide reference and guidance for the development of high-quality Android applications.