Preface
Recent projects to achieve such an effect: After running, to have a service is always running in the background, regardless of what the user does to ensure that the service is not killed, this is really a problem. How can you ensure that your service is not killed by referring to the various custom versions of system and security vendor Gadfly software today?
In fact, in addition to the conventional means, we can refer to and set-Program-is running, you can see that the two processes and services are opened at the same time:
"Interested in studying Daemons and Aidl."
I guess it's supposed to be listening to each other, if one of them is killed, and the other catches up to start immediately to reach the state that the service is always running, it looks like is the same principle, specifically whether it is this way, and yet to be consulted, I have yet to fathom how they are realized, First of all, a brief introduction of my own control measures, first introduce the service concept, memory is not good, repeat to build the wheel, master can directly see the last.
Service Introduction
The service is run in the background for an indefinite period of time and does not interact with the user application component. Each service must be declared by <service> in manifest. Can be started by Contect.startservice and Contect.bindserverice. As with other application components, it runs in the main thread of the process. This means that if the service requires a lot of time-consuming or blocking operations, it needs to be implemented in its child threads (or with a system-provided intentservice that inherits the service, which processes the data with its own new thread). " of course you can also startservice in a new thread, so the service is not mainthread "
Local Service Local Service for internal application
It can start and run until someone stops it or it stops itself. In this way, it starts with a call to Context.startservice () and ends with a call to Context.stopservice (). It can call Service.stopself () or Service.stopselfresult () to stop itself. No matter how many times the StartService () method is called, you only need to call once StopService () to stop the service.
"Some time-consuming tasks for implementing the application itself, such as querying the upgrade information, and not consuming the application such as the activity's thread, but the single-threaded background execution, so the user experience is better"
Remote Service Remote Service is used between applications within the Android system
It can be manipulated by its own defined and exposed interfaces. The client establishes a connection to the service object and invokes the service through that connection. The connection is established to call the Context.bindservice () method to call Context.unbindservice () to close. Multiple clients can bind to the same service. If the service is not loaded at this time, bindservice () loads it first.
"Can be reused by other applications, such as weather forecasting services, other applications do not need to write such services, call the existing can be"
The life cycle of 1,service
2,service operating mode
Starting the service with StartService (), the system will search through the incoming intent for services related to the information in the intent. If the service does not start, run OnCreate first, and then run Onstartcommand (which can handle the intent and other parameters that are passed in at startup) until a significant call to StopService or stopself stops the service. No matter how many times you run StartService, StopService or stopself,service will stop whenever you call. Use the stopself (int) method to ensure that the intent is processed and then stopped. Onstartcommand, the start function for the service was introduced after 2.0 and 2.0 was public void OnStart (Intent Intent, int startid).
The service is enabled with the Bindservice () method, and the caller is bound together with the service, and once the caller exits, the service terminates. Onbind () The method is only invoked when the service is started with the Context.bindservice () method. This method is called when the caller and the service are bound, and the Context.bindservice () method is called multiple times when the caller is tied to the service and does not cause the method to be called more than once. Using the Context.bindservice () method to start a service can only call the Onunbind () method to disassociate the caller from the service and call the OnDestroy () method at the end of the service.
3, the process with the service has a higher priority
The official documentation tells us that the Android system will try to keep the process running with the service as long as the service has been started (start) or the client is connected (Bindservice) to it. When memory is low, it needs to be maintained, and the process with the service has a higher priority.
1. If the service is calling the Oncreate,onstartcommand or Ondestory method, then the process used for the current service becomes the foreground process to avoid being killed.
2. If the current service has been started (start), the process that owns it has a lower priority than those visible to the user, but is more important than the invisible process, which means that the service is generally not killed.
3. If the client is already connected to service (Bindservice), the process that owns the service has the highest priority and can be considered to be visible.
4. If the service can use the startforeground (int, Notification) method to set the service as the foreground state, the system is considered to be visible to the user and does not killed when the memory is low.
5. If there are other application components running in the same process as service,activity, it will increase the importance of the process.
Guaranteed service not to be killed
Onstartcommand method, returning Start_sticky
Startcommond Several constant parameters introduction:
1, Start_sticky
After the service process is killed after running Onstartcommand, that will remain in the start state, but those incoming intent are not preserved. Shortly after the service tries to recreate it again, because it remains in the start state, it is guaranteed to call Onstartcommand after the service is created. If no start command is passed to the service, that will get the intent to null.
2, Start_not_sticky
After the service process is killed after running Onstartcommand, and no new intent is passed to it. The service moves out of the start state and is not re-created until a new, obvious method (StartService) call is made. Because if no intent is passed, then the service will not start, that is, the period Onstartcommand will not receive any null intent.
3, Start_redeliver_intent
After the service process is killed after running Onstartcommand, the service is started again and the last intent is passed to Onstartcommand. The pass-through intent is not stopped until stopself (int) is called. If there is still an unhandled intent after the kill, the service will start automatically after the kill. Therefore, Onstartcommand does not receive any null intent.
[Java]View Plaincopy
- @Override
- public int Onstartcommand (Intent Intent, int flags, int startid) {
- Flags = Start_sticky;
- return Super.onstartcommand (intent, flags, Startid);
- }
"Conclusion" manual return Start_sticky, pro-Test when the service is killed due to insufficient memory, when the memory is again, the service is re-created, it is good, but can not be guaranteed to be rebuilt under any circumstances, such as the process was killed ....
Improve service Priority
In the Androidmanifest.xml file, for Intent-filter, you can set the highest priority by Android:priority = "1000", 1000 is the highest value, and if the number is smaller, the lower the priority and applies to the broadcast.
[Java]View Plaincopy
- <service
- Android:name="Com.dbjtech.acbxt.waiqin.UploadService"
- android:enabled="true" >
- <intent-filter android:priority="> "
- <action android:name="Com.dbjtech.myservice"/>
- </intent-filter>
- </service>
"Conclusion" it appears that the priority attribute seems to apply only to broadcast, which may not be valid for service
Elevate Service Process Priority
Processes in Android are managed, and when the system process is tight, the process is automatically recycled according to the priority level. Android divides the process into 6 levels, which are ranked from highest to lowest in order of precedence:
1. Foreground process (Foreground_app)
2. Visual process (Visible_app)
3. Secondary service process (Secondary_server)
4. Background process (Hidden_app)
5. Content Provisioning Node (content_provider)
6. Empty process (Empty_app)
When the service is running in a low-memory environment, some of the existing processes will be killed. Therefore, the priority of the process will be important, and you can use Startforeground to put the service into the foreground state. This will reduce the chance of being killed at low memory.
Add the following code within the Onstartcommand method:
[Java]View Plaincopy
-
- Notification Notification = new Notification (R.drawable.ic_launcher,
-
- GetString (R.string.app_name), System.currenttimemillis ());
-
-
-
- Pendingintent pendingintent = pendingintent.getactivity (this, 0,
-
- New Intent (This, Appmain. Class), 0);
-
- Notification.setlatesteventinfo (This, "Uploadservice", "please keep the program running in the background",
-
- Pendingintent);
-
- <span style="color: #ff0000;" > Startforeground (0x111, notification);</span>
Note that in OnDestroy you also need Stopforeground (true), the runtime will see your app in the drop-down list:
"Conclusion" if under extreme low memory pressure, the service will still be killed, and will not necessarily be restart
Restart service in the OnDestroy method
Service +broadcast mode, that is, when the service goes ondestory, send a custom broadcast, when the broadcast, restart service;
[Java]View Plaincopy
- <receiver android:name="Com.dbjtech.acbxt.waiqin.BootReceiver" >
- <intent-filter>
- <action android:name="Android.intent.action.BOOT_COMPLETED"/>
- <action android:name="Android.intent.action.USER_PRESENT"/>
- <action android:name="Com.dbjtech.waiqin.destroy"/>//This is a custom action
- </intent-filter>
- </receiver>
At the time of OnDestroy:
[Java]View Plaincopy
- @Override
- Public void OnDestroy () {
- Stopforeground (true);
- Intent Intent = new Intent ("Com.dbjtech.waiqin.destroy");
- Sendbroadcast (Intent);
- Super.ondestroy ();
- }
In the Bootreceiver.
[Java]View Plaincopy
-
- Public class Bootreceiver extends Broadcastreceiver {
-
-
-
- @Override
-
- public void OnReceive (context context, Intent Intent) {
-
- if (intent.getaction (). Equals ("Com.dbjtech.waiqin.destroy")) {
-
- //todo
-
- //write about restarting the service here
-
- Startuploadservice (context);
-
- }
-
-
-
- }
-
-
-
- }
can also be directly in the OnDestroy () StartService
[Java]View Plaincopy
- @Override
- Public void OnDestroy () {
-
- Intent sevice = new Intent (This, Mainservice. Class);
- This.startservice (sevice);
-
- Super.ondestroy ();
- }
"Conclusion" when using a third-party application such as a port steward or in a setting-application-Force stop, the app process may be killed directly, and the OnDestroy method cannot get in, so there is no guarantee ~.~
Application Plus Persistent property
Look at the Android documentation to know that when the process is inactive for a long time, or when the system needs resources, it automatically cleans up the portal, kills some of the service, and the invisible activity of the process. But if a process does not want to be killed (such as a data caching process, or a status monitoring process, or a remote service process), you can do this:
[Java]View Plaincopy
- <application
- Android:name="Com.test.Application"
- android:allowbackup="true"
- android:icon="@drawable/ic_launcher"
- Android:label="@string/app_name"
- <span style="color: #ff0000;" > android:persistent="true" </span>
- Android:theme="@style/apptheme" >
- </application>
"Conclusion" It is said that this property can not be set randomly, but after the setting, it is found that the priority has improved a lot, perhaps the equivalent of a system-level process, but there is no guarantee of survival
Monitoring System broadcast Judging service status
Through some of the system's broadcasts, such as: Phone restart, interface wake-up, application status changes, and so on to monitor and capture, and then determine whether our service is still alive, do not forget to add permissions ah.
[Java]View Plaincopy
-
- <receiver android:name="Com.dbjtech.acbxt.waiqin.BootReceiver" >
-
- <intent-filter>
-
- <action android:name="Android.intent.action.BOOT_COMPLETED"/>
-
- <action android:name="Android.intent.action.USER_PRESENT"/>
-
- <action android:name="Android.intent.action.PACKAGE_RESTARTED"/>
-
- <action android:name="Com.dbjtech.waiqin.destroy"/>
-
- </intent-filter>
-
- </receiver>
In Broadcastreceiver:
[Java]View Plaincopy
-
- @Override
-
- Public void OnReceive (context context, Intent Intent) {
-
- if (Intent.ACTION_BOOT_COMPLETED.equals (Intent.getaction ())) {
-
- System.out.println ("mobile phone is on ....");
-
- Startuploadservice (context);
-
- }
-
- if (Intent.ACTION_USER_PRESENT.equals (Intent.getaction ())) {
-
- Startuploadservice (context);
-
- }
-
- }
"Conclusion" This can be considered as a measure, but the sense of monitoring more can lead to service confusion, causing a lot of inconvenience
Install apk to/system/app, change the system-level application This method is not recommended, because if your app is for users, it is not appropriate, I am to give the test sister to use, this app is also very simple to use, Open the service and ensure that it stays in the background, boot from boot. But yesterday found that if her Huawei mobile phone for a long time off, and then reopen, we apply the service will not start, it seems that the broadcast can not receive the ~ rage, intended to become a system application. Premise: Root over the phone 1, the code is written, packaged and exported apk,copy to the phone SD card root directory. 2, phone connection eclipse,cmd:adb shell3, switch root mode, input: su (if root is not error) 4, set the system to read and write permissions:mount –o Remount rw /system (System default is read-only, unable to write, this step is critical) 5,CD to the SD card and directory, confirm that we have copied to the SD card root directory of the APK (generally storage/sdcard0) [ email protected]:/# CD Storage/sdcard06, the most critical step, we're going to copy the apk into/system/app: found that the copy command is invalid ~ Then we'll use push: if there is an error: device Not found, then the mobile phone download a root explorer to find apk,copy to System/app, through the app is easier. 7,system/app sure to have our apk, restart the phone: Settings-application Management, check: You can see our app has been unable to uninstall, can only deactivate this time, even if the force stopped, or shut down the service, restart the phone can still get up service~! System-level apps so that some third-party butler software can't kill us unless you deactivate the app or force it to stop (but my app can boot). "Conclusion" this way is suitable for debugging to use, not a solution, you can try in the running interface: forced to shut down Sohu video two processes, restart the phone, found that he can start again, but if replaced by our app, forced to stop, the process hangs, and then restart the phone, I can't start it. ~ We study together, how to like Sohu Video, open two processes, mutual monitoring, to achieve maximumDegree of survival, if this can be achieved, then and, and so on the same effect.
How Android is developed to ensure service is not killed (Broadcast+system/app)