Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在上一个活动中调用startService时,bindService失败_Android_Service - Fatal编程技术网

Android 在上一个活动中调用startService时,bindService失败

Android 在上一个活动中调用startService时,bindService失败,android,service,Android,Service,我不确定如何解决这个问题,但在一个活动中,我调用startService,然后立即调用启动下一个活动 这样,服务启动,并开始按预期处理数据 我转到下一个活动,在onResume中调用AsyncTask绑定服务 因此,基本流程是调用AsyncTask,bindService返回false,因此永远不会调用mConnection 所以,问题是为什么bindService返回false 我将绑定放在AsyncTask中的原因是,在绑定之前,我让线程休眠了10秒钟,以查看服务是否需要首先启动 我也在这个

我不确定如何解决这个问题,但在一个活动中,我调用startService,然后立即调用启动下一个活动

这样,服务启动,并开始按预期处理数据

我转到下一个活动,在
onResume
中调用
AsyncTask
绑定服务

因此,基本流程是调用AsyncTask,
bindService
返回false,因此永远不会调用mConnection

所以,问题是为什么
bindService
返回false

我将绑定放在AsyncTask中的原因是,在绑定之前,我让线程休眠了10秒钟,以查看服务是否需要首先启动

我也在这个活动中启动了服务,首先是在onCreate方法中,因此等待了10秒钟,但是
bindService
仍然返回false

private class BindServiceTask extends AsyncTask<Void, Void, Boolean> {
    protected Boolean doInBackground(Void... params) {
        return bindService(
                new Intent(IMyCallback.class.getName()),
                mConnection, Context.BIND_AUTO_CREATE);
    }
    protected void onPostExecute(Boolean b) {
        if (b) {
            Log.i(TAG, "onResume - binding succeeded");
            Toast.makeText(mContext, "Bound to service succeeded",
                    Toast.LENGTH_LONG).show();
        } else {
            Log.i(TAG, "onResume - binding failed");
            Toast.makeText(mContext, "Bound to service failed",
                    Toast.LENGTH_LONG).show();
        }
    }
}
private IMyCallback mCallback = new IMyCallback.Stub() {
    @Override
    public void dataChanged(double[] info) throws RemoteException {
        mHandler.sendMessage(mHandler.obtainMessage(LOCATION_MSG, info));
    }
};
IMyService mIRemoteService;
private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        Log.i(TAG, "onServiceConnected");
        mIRemoteService = IMyService.Stub.asInterface(service);
        try {
            Log.i(TAG, "registering callback");
            mIRemoteService.registerCallback(mCallback);
        } catch (RemoteException e) {
            Log.e(TAG, e.toString());
        }
    }

    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "Service has unexpectedly disconnected");
        mIRemoteService = null;
    }
};
私有类BindServiceTask扩展了AsyncTask{
受保护的布尔doInBackground(Void…params){
退货服务(
新意图(IMyCallback.class.getName()),
mConnection,Context.BIND\u AUTO\u CREATE);
}
受保护的void onPostExecute(布尔b){
如果(b){
Log.i(标记“onResume-binding successed”);
Toast.makeText(mContext,“绑定到服务成功”,
Toast.LENGTH_LONG).show();
}否则{
Log.i(标记“onResume-绑定失败”);
Toast.makeText(mContext,“绑定到服务失败”,
Toast.LENGTH_LONG).show();
}
}
}
private IMyCallback mCallback=新的IMyCallback.Stub(){
@凌驾
public void dataChanged(double[]info)引发RemoteException{
mHandler.sendMessage(mHandler.ActainMessage(位置消息,信息));
}
};
IMyService mIRemoteService;
专用ServiceConnection mConnection=新ServiceConnection(){
服务连接上的公共无效(组件名称类名称,IBinder服务){
Log.i(标记“onServiceConnected”);
mIRemoteService=IMyService.Stub.asInterface(服务);
试一试{
Log.i(标记“注册回调”);
mIRemoteService.registerCallback(mCallback);
}捕获(远程异常){
Log.e(标记,e.toString());
}
}
ServiceDisconnected上的公共void(ComponentName类名称){
Log.e(标记“服务意外断开”);
mIRemoteService=null;
}
};

当您调用
bindService()
时,它不一定会返回您的服务连接或API来访问服务。它是异步发生的。您需要这样的回调:

class PictureUploadQueueServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName name, IBinder service){
        Log.d(TAG, "PictureUpload Service Connected!");            
        pictureUploadQueueApi = PictureUploadQueueServiceApi.Stub.asInterface(service);       
    }

    public void onServiceDisconnected(ComponentName name){
        Log.d(TAG, "PictureUpload Service Connection Closed!");
        pictureUploadQueueApi = null;
    }
};
getApplicationContext().bindService(new Intent("org.me.xxxx.PictureUploadQueueServiceApi"),
                        pictureUploadQueueServiceConnection,
                        Context.BIND_AUTO_CREATE
                );
interface PictureUploadQueueServiceApi {

        void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback);

        boolean isEmpty();

    }
执行绑定的调用应如下所示:

class PictureUploadQueueServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName name, IBinder service){
        Log.d(TAG, "PictureUpload Service Connected!");            
        pictureUploadQueueApi = PictureUploadQueueServiceApi.Stub.asInterface(service);       
    }

    public void onServiceDisconnected(ComponentName name){
        Log.d(TAG, "PictureUpload Service Connection Closed!");
        pictureUploadQueueApi = null;
    }
};
getApplicationContext().bindService(new Intent("org.me.xxxx.PictureUploadQueueServiceApi"),
                        pictureUploadQueueServiceConnection,
                        Context.BIND_AUTO_CREATE
                );
interface PictureUploadQueueServiceApi {

        void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback);

        boolean isEmpty();

    }
确保在您的服务中实现API存根,并在
onBind()方法中返回它的实例:

private PictureUploadQueueServiceApi.Stub api = new PictureUploadQueueServiceApi.Stub() {
    @Override
    public void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback) throws RemoteException {
        appendPictureUpload(remoteURI, localURI, target, description, callback);
    }
    @Override
    public boolean isEmpty() {
        return queue.size() == 0 ? true : false;
    };
};

@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "Bound Intent: " + intent);
    return api;
}
最后,为了完成示例,我的示例的AIDL文件如下所示:

class PictureUploadQueueServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName name, IBinder service){
        Log.d(TAG, "PictureUpload Service Connected!");            
        pictureUploadQueueApi = PictureUploadQueueServiceApi.Stub.asInterface(service);       
    }

    public void onServiceDisconnected(ComponentName name){
        Log.d(TAG, "PictureUpload Service Connection Closed!");
        pictureUploadQueueApi = null;
    }
};
getApplicationContext().bindService(new Intent("org.me.xxxx.PictureUploadQueueServiceApi"),
                        pictureUploadQueueServiceConnection,
                        Context.BIND_AUTO_CREATE
                );
interface PictureUploadQueueServiceApi {

        void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback);

        boolean isEmpty();

    }

问题似乎是清单有问题

我缺少用于告诉系统哪些服务可以绑定到的意图过滤器:

    <service
        android:name=".MyService"
        android:process=":remote" >
        <intent-filter>

            <!--
                 These are the interfaces supported by the service, which
                 you can bind to.
            -->
            <action android:name="my.com.services.IMyCallback" />
            <action android:name="my.com.services.IMySecondaryService" />
            <!--
                 This is an action code you can use to select the service
                 without explicitly supplying the implementation class.
            -->
            <action android:name="my.com.activity.MY_SERVICE" />
        </intent-filter>
    </service>


如果您使用的是AIDL,您是否缺少API和连接创建回调?你能发布错误/stacktrace吗?@Jonathan-没有错误,只是当我调用bindService时,值为false。mConnection是回调函数,我认为没有必要包含它,因为bindService失败了。bindService很可能没有失败,因为服务不会总是,或者很少,在该调用中完全实例化和绑定。我刚刚发布了我正在做的一个项目的一些片段。当我第一次实现和AIDL服务API时,我非常激动。现在我明白了,我固执地在我所有的服务实现中使用它,尽管还有其他的选择。看起来我正在执行所有这些步骤,但可能有一些我遗漏了。@JamesBlack特别是,您的代码没有考虑绑定是异步的。您需要设置一个简单的状态机来处理服务连接的“生命周期”。最后!经过数小时的调试-_-