I have a service

Manifest

<service android:name=".SocketService" android:process=":socket"/> 

I connect to it via bindService and use AIDL

The service is designed to exchange data with the server and the application. The service has no intent filters.

 public final class SocketService extends Service { @Override public IBinder onBind(Intent intent) { return new Binder(); } private final class Binder extends ISocketService.Stub { @Override public void on(String event, ISocketEmitterListener listener) throws RemoteException { ... } @Override public int emit(String event, byte[] bytes) throws RemoteException { ... return 0; } } @Override public boolean onUnbind(Intent intent) { boolean stopSelf = DBManager.getBoolean(DBManager.SOCKET_SERVICE_STOP_SELF); if (stopSelf) { stopSelf(); DBManager.save(DBManager.SOCKET_SERVICE_STOP_SELF, false); } Timber.i("SocketService unbinded!"); return super.onUnbind(intent); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Timber.i("SocketService started!"); ... return START_STICKY; } @Override public void onTaskRemoved(Intent rootIntent) { stopSelf(); Timber.i("SocketService task removed!"); super.onTaskRemoved(rootIntent); } @Override public void onDestroy() { DBManager.save(DBManager.SOCKET_SERVICE_IS_RUNNING, false); Timber.i("SocketService destroyed!"); } } 

My problem is that when an application receives any error and crashes, or simply closes incorrectly, for example, it is unloaded by the user through the task manager, then the next launch of the service is no longer possible! To do this, you need to reinstall the application, otherwise it writes this: ActivityManager: Unable to start service Intent { cmp=package.name/.SocketService} U=0: not found

How to get rid of this WITHOUT APPLICATION RESET ?

I have already tried many ways: 1) Redefine Thread.UncaughtExceptionHandler and make there an undind and stopService service before System.exit(1) 2) Ovveride onTaskRemoved() with stopSelf() inside 3) Itd ...

Now I have made such a method for checking, so that if anything to inform the user that he must reinstall the application because of this error.

 public static boolean checkOnNonNull(Context context, Class<?> clazz) { Intent service = new Intent(context, clazz); ResolveInfo rInfo = context.getPackageManager().resolveService(service, PackageManager.GET_SHARED_LIBRARY_FILES); ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { Timber.e("Unable to start service " + service + ": not found"); return false; } return true; } 

UPD I did some tests and it’s as if the record actually disappears from the manifest, because I started adding numbers to the class name and the service started working with a new name. But all the old names were not found.

 <service android:name=".SocketService+[1-10]" android:process=":socket"/> // Затем я подставлял цифры в обратном порядке и .SocketService9 будучи использованным один раз уже not found. 
  • I read about a similar problem that is closer to my stackoverflow.com/questions/17780049/… - Sergey
  • Does your service need a separate process ( android:process=":socket" )? Looking at en-SO for this problem - the reasons may be the car. So give more details. The service is inside the application or outside, the manifest does not hurt to show (at least in general terms) how and where the service call occurs? - woesss
  • android: process = ": socket" - yes, this is amazing, because this service is used by the application itself and another service that is also in another process. And this service should live independently of the life of one or the other. There is absolutely nothing special about the manifesto. Service is bindit and the application itself and in another service. If one or the other is completed, stopSelf () is put in onUnbind so that if another client is still able to use it. Well, it's from mana, everything is logical. - Sergey
  • And if the application is running and a new version is installed on top, the exact same error occurs. The same is true when developing in AS, building a project for a real device, and if it remains running and I make the next build, then the service is not already found. It turns out as if he is not registered with me in the manifesto, but in fact he is registered! but after any departure he seems to disappear from the manifesto ... - Sergey

1 answer 1

The only working option when the service is disabled as a component is to turn it on manually:

 public static boolean checkOnNonNull(Context context, Class<?> clazz) { Intent service = new Intent(context, clazz); ResolveInfo rInfo = context.getPackageManager().resolveService(service, PackageManager.GET_SHARED_LIBRARY_FILES); ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { Timber.e("Unable to start service " + service + ": not found"); return false; } return true; } if (!checkOnNonNull(context, MyServiceClass.class)) { ComponentName component = new ComponentName(getPackageName(), MyServiceClass.class.getName()); getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); }