首页 > 解决方案 > 远程服务 - 无法启动服务 Intent U=0 not found

问题描述

我有一个套接字服务

显现

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

我通过它连接bindService 并使用AIDL

该服务旨在与服务器和应用程序交换数据。该服务没有意图过滤器。

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!");
    }
}

我的问题是,当应用程序收到任何错误并崩溃,或者只是不正确地关闭时,例如,它被用户通过任务管理器卸载,下一次服务启动是不可能的!为此,您需要重新安装应用程序,否则它会这样写: ActivityManager: Unable to start service Intent { cmp=package.name/.SocketService} U=0: not found

如何在不重新安装应用程序的情况下摆脱这种情况?

我已经尝试了很多方法:1)覆盖Thread.UncaughtExceptionHandler并在此之前执行 undind 和 stopService System.exit(1) 2)Ovveride onTaskRemoved()with stopSelf()inside 3)等等...

现在我做了这样一种检查方法,以便如果有任何事情通知用户他必须重新安装应用程序,因为这个错误。

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 我进行了一些测试,结果好像清单中的记录真的消失了,因为我开始在类名中添加数字,并且服务开始使用一个新的名称。但是所有的旧名字都没有找到。

<service
    android:name=".SocketService+[1-10]"
    android:process=":socket"/>
// Then I put the numbers in reverse order and .SocketService9 useded once already not found.

标签: androidservice

解决方案


当服务作为组件被禁用时,唯一的工作选项是手动打开它:

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);
}

推荐阅读