This article first looks at this knowledge point will have what will appear in the interview, first to understand the topic. We’ll look at what the Service doesn’t ask about again.
What is Service
Service is one of Android’s four major components. It is an application component that can run operations in the background for a long time without a user interface.
There are two ways to start a Service :startService and bindService.
Note: A service runs in the main thread of its managed process, just like any other application object. This means that if your Service is performing any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should create another child thread in the Service and then handle time-consuming operations there.
Service startup mode
startService
- Start the Service
To explicitly start the Service, specify the class of the Service in the Intent and call startService (lntent).
final Intent intentStart = new Intent(ServiceActivity.this, StartService.class);
startService(intentStart);
Copy the code
In the above code, the Intent indicates that the Service to start is of the class StartService.
When a Service is started this way, there is no connection between the visitor and the Service, and the Service still runs even if the visitor exits.
- Stop the service
To explicitly start and stop a Service, you need to pass the Intent that started the Service to the stopService (Intent) function.
stopService(intentStart);
Copy the code
Starting with Android5.0, Google requires you to start a Service with an Intent, so we don’t cover implicit launching.
bindService
- Start the Service using the bindService() method
The binding mode starts a Service using the bindService() method in the following format:
bindService(Intent service,ServiceConnection conn,int flags);
Copy the code
The parameters are described as follows:
-
Service: This parameter specifies the service to be started with the Intent.
-
Conn: This parameter is a ServiceConnnection object. If the binding is successful, the system calls the onServiceConnected () method of ServiceConnnection. The onServiceDisconnected method in ServiceConnnection is called.
-
Flags: This parameter specifies whether the Service is automatically created when binding. If BIND_AUTO_CREATE is specified, it is automatically created. If 0 is specified, it is not automatically created.
In binding mode, onCreate() and onBinde () are called successively when the caller binds a Service via bindService().
By starting a Service this way, the visitor is bound to the Service, and the Service terminates once the visitor exits.
- Unbind using the unbindService() method
Unbind simply by using the unbindService() method and passing the ServiceConnnection to the unbindService() method.
Note, however, that onServiceConnected() is not called once the unbindService() method succeeds, because onServiceConnected() is called only when the binding is accidentally broken.
The onUnbind() function is called when the caller unbinds the Service through the unbindService() function. If onUnbind() returns true, it means that onRebind () will be called when the service is rebound.
StartService sample
- OnCreate (), onStartCommand(), onBind(), onDestroy();
public class StartService extends Service {
@Override
public void onCreate(a) {
super.onCreate();
MLog.e(getClass().getName(), "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
MLog.e(getClass().getName(), "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy(a) {
MLog.e(getClass().getName(), "onDestroy");
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null; }}Copy the code
- Create serviceActivity.java and the accompanying activity_service.xml file with the following code:
public class ServiceActivity extends ActivityBase {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
Intent intentStart = new Intent(ServiceActivity.this, StartService.class);
findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { startService(intentStart); }}); findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { stopService(intentStart); }}); }}Copy the code
- The accompanying activity_service.xml file
<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/color_666666">
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=Start start service/>
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start stop service"/>
</LinearLayout>
Copy the code
- Add a Service component declaration and declare a Service component in the androidmanifest.xml file with the following code:
<? xml version="1.0" encoding="utf-8"? > <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.scc.demo"> <application ... > <activity ... > <intent-filter> ... </intent-filter> </activity> <service android:name=".service.StartService"/>
</application>
</manifest>
Copy the code
- The results
07-07 16:41:11.474 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
07-07 16:41:11.481 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
07-07 16:41:11.482 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
07-07 16:41:13.313 E/-SCC-com.scc.demo.service.StartService: onCreate
07-07 16:41:13.334 E/-SCC-com.scc.demo.service.StartService: onStartCommand
07-07 16:41:16.705 E/-SCC-com.scc.demo.service.StartService: onDestroy
Copy the code
BindService sample
- OnCreate (), onBind(), onUnbind(), onDestroy();
public class BindService extends Service {
// Declare an interface variable mBinder for the IBinder interface
public final IBinder mBinder = new LocalBinder();
private NotificationManager mNM;
private int NOTIFICATION = R.string.local_service_started;
//LocalBinder is an inner class that inherits Binder
public class LocalBinder extends Binder {
public BindService getService(a) {
return BindService.this; }}@Override
public void onCreate(a) {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
MLog.e(getClass().getName(), "onCreate");
showNotification();
}
@Override
public void onDestroy(a) {
MLog.e(getClass().getName(), "onDestroy");
mNM.cancel(NOTIFICATION);
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
@Override
public IBinder onBind(Intent intent) {
MLog.e(getClass().getName(), "onBind");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
MLog.e(getClass().getName(), "onUnbind");
return super.onUnbind(intent);
}
private void showNotification(a) {
CharSequence text = getText(R.string.local_service_started);
PendingIntent contentIntent = PendingIntent.getActivity(this.0.new Intent(this, ServiceActivity.class), 0);
Notification notification = new Notification.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setTicker(text) .setWhen(System.currentTimeMillis()) .setContentTitle(getText(R.string.local_service_label)) .setContentText(text) .setContentIntent(contentIntent) .build(); mNM.notify(NOTIFICATION, notification); MLog.e(getClass().getName(),"Noticeboard out"); }}Copy the code
- Create serviceActivity.java and the accompanying activity_service.xml file with the following code:
public class ServiceActivity extends ActivityBase {
private BindService bindService;
private boolean isBind = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
findViewById(R.id.btn_bind).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(! isBind) { Intent intentBind =new Intent(ServiceActivity.this, BindService.class);
bindService(intentBind, serviceConnection, Context.BIND_AUTO_CREATE);
isBind = true; }}}); findViewById(R.id.btn_unbing).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isBind) {
isBind = false;
unbindService(serviceConnection);
bindService = null; }}}); }private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MLog.e(getClass().getName(), "onServiceConnected");
bindService = ((BindService.LocalBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
MLog.e(getClass().getName(), "onServiceDisconnected");
bindService = null; }}; }Copy the code
- The accompanying activity_service.xml file
<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/color_666666">
<Button
android:id="@+id/btn_bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bind service binding"/>
<Button
android:id="@+id/btn_unbing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bind"/>
</LinearLayout>
Copy the code
- Add a Service component declaration and declare a Service component in the androidmanifest.xml file with the following code:
<? xml version="1.0" encoding="utf-8"? > <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.scc.demo"> <application ... > <activity ... > <intent-filter> ... </intent-filter> </activity> <service android:name=".service.BindService"/>
</application>
</manifest>
Copy the code
- The results
07-07 17:00:04.309 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
07-07 17:00:04.350 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
07-07 17:00:04.350 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
07-07 17:00:10.088 E/-SCC-com.scc.demo.service.BindService: onCreate
07-07 17:00:10.120E/SCC - com. SCC. Demo. Service. BindService: notification bar has been out07-07 17:00:10.145 E/-SCC-com.scc.demo.service.BindService: onBind
07-07 17:00:10.164 E/-SCC-com.scc.demo.actvitiy.ServiceActivity$5: onServiceConnected
07-07 17:00:39.111 E/-SCC-com.scc.demo.service.BindService: onUnbind
07-07 17:00:39.134 E/-SCC-com.scc.demo.service.BindService: onDestroy
Copy the code
Service life cycle
onBind()IBinder is a method that a Service must implement. The returned IBinder object acts as a proxy object for the Service component. The Service allows other program components to access the internal data of the Service through the IBinder object, so that communication between other program components and the Service can be realized.
StartService Startup life cycle
OnCreate () is called by the system when the Service is first created.
OnStartCommand () This method is called when the startService method starts a Service.
OnDestroy () Called by the system when Service is no longer in use.
Note: A startService is only created once and destroyed once, but can be started multiple times, so the onCreate() and onDestroy() methods are called only once and the onStart() method multiple times.
BindService startup life cycle
OnCreate () is called by the system when a Service is created.
OnBind () Is called when the bindService method starts a Service.
OnUnbind () This method is called when the unbindService method unbinds.
OnDestroy () Called by the system when Service is no longer in use.
Note: A bindService can be created multiple times, destroyed multiple times, and reused.
The difference between a Service and a Thread
A Service is a system component in Android. It runs in the main thread of an independent process and cannot perform time-consuming operations.
Thread is the smallest unit of program execution, the basic unit of CPU allocation, and can enable child threads to perform time-consuming operations.
You can obtain instances of a Service in different activities to operate the Service easily.
Thread instances are difficult to obtain from different activities, and if the Activity is destroyed, Thread instances are difficult to obtain again.
Use IntentService
IntentService is a subclass of Scrvice, so it is not a normal Service. It adds extra functionality over a normal Service.
Let’s start with two problems with the Service itself.
- A Service does not start a separate process; it is in the same process as the application in which it resides.
- A Service is not a new thread, so time-consuming tasks should not be handled directly within a Service.
IntentService makes up for Service.
IntentService features:
- IntentService creates a separate worker thread to handle all Intent requests.
- IntentService creates a separate worker thread to handle the code that implements the onHandleIntent() method, so developers don’t have to deal with multithreading.
IntentService instance
- Create sccintentService.java from IntentService, override onHandleIntent() and create a constructor with no arguments:
public class SccIntentService extends IntentService {
public SccIntentService(a) {
super("SccIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
MLog.e(getClass().getName(), "onHandleWork");
for (int i = 0; i < 3; i++) {
try {
MLog.e(getClass().getName(), Number: "start"+i);
Thread.sleep(10000);
MLog.e(getClass().getName(), "End of the Number:+i);
} catch(InterruptedException e) { e.printStackTrace(); }}}@Override
public void onDestroy(a) {
super.onDestroy();
MLog.e(getClass().getName(), "onDestroy"); }}Copy the code
- Add IntentService component declaration and declare a Service component in the androidmanifest.xml file with the following code:
<service android:name=".service.SccIntentService"/>
Copy the code
- Start the SccIntentService
startService(new Intent(ServiceActivity.this, SccIntentService.class));
Copy the code
- The results
07-07 18:00:39.505 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
07-07 18:00:39.531 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
07-07 18:00:39.531 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
07-07 18:01:12.690 E/-SCC-com.scc.demo.service.SccIntentService: onHandleWork
07-07 18:01:12.690E/SCC - com. SCC. Demo. Service. SccIntentService: Number: start0
07-07 18:01:22.691E/SCC - com. SCC. Demo. Service. SccIntentService: Number: the end0
07-07 18:01:22.697E/SCC - com. SCC. Demo. Service. SccIntentService: Number: start1
07-07 18:01:32.698E/SCC - com. SCC. Demo. Service. SccIntentService: Number: the end1
07-07 18:01:32.698E/SCC - com. SCC. Demo. Service. SccIntentService: Number: start2
07-07 18:01:42.699E/SCC - com. SCC. Demo. Service. SccIntentService: Number: the end2
07-07 18:01:42.716 E/-SCC-com.scc.demo.service.SccIntentService: onDestroy
Copy the code
When a common Service performs time-consuming operations for 20 seconds, the main thread is blocked and the ANR(program no response) is abnormal.
- IntentService performs 30S of time-consuming operations without blocking the main thread or generating ANR. As shown in the figure above, no ANR is generated during normal operation, which lasts for 30S from 18:01:12 to 18:01:42.
- IntentService also has the benefit of running out. After performing the time-consuming operation in onHandleIntent(), call onDestroy() to disable it.