Android: get result from a service

2019-08-03 06:43发布

I have android service which I need to return a result after it has been started. So:

1) I start the service

2) The service does something

3) The service returns a result

I thought that maybe I can use a singleton class to take the result. I created a singleton class in order to make the service save the result in it and then take the result from the service by an activity. Here there's the code of the class:

public class Result {

    //SIGLETON DECLARATION

    private static Result mInstance = null;

    public static Result getInstance() { 
        if (mInstance == null) {
            mInstance = new Result();
        }
        return mInstance;
    }

    private Result() {
    }

    //CODE

    Object result;
    boolean resultIsSet = false;

    public void deletePreviousResult() {
        this.result = null;
        resultIsSet = false;
    }

    public void setResult(Object result) {
        Log.w("result", "setResult");
        this.result = result;
        resultIsSet = true;
    }

    public Object getResult() {
        Log.w("result", "getResult");
        while(resultIsSet == false) {}
        return this.result;
    }

Here's the code that I use to get the result:

public int getInfo() {
    Result.getInstance().deletePreviousResult();
    //start the service and ask to save the result in singleton class
    Intent myIntent = new Intent(mInstanceContext, MediaPlayerService.class);
    myIntent.setAction("getInfo");
    mInstanceContext.startService(myIntent);
    //take the result
    return (Integer) Result.getInstance().getResult();
}

What is doing in onStartCommand is:

 Result.getInstance().setResult(mMediaPlayer.getCurrentPosition()); 

where mMediaPlayer is a MediaPlayer object.

However the problem is that if setResult is also supposed to be called in onStartCommand, it is never called! Why? Is it my approach wrong?

1条回答
来,给爷笑一个
2楼-- · 2019-08-03 07:19

This code you have in getInfo():

mInstanceContext.startService(myIntent);
//take the result
return (Integer) Result.getInstance().getResult();

assumes that when you call startService() the service is started and onStartCommand() is called synchronously so that in the next statement you can get the result using Result.getInstance().getResult().

Unfortunately, it doesn't work that way. Calling startService() isn't like calling a method on an object. What you do when you call startService() is that you tell Android that you want that service to be started at the next available moment. Since onStartCommand() in your service needs to be called on the main thread, usually this means that Android will start your service and call onStartCommand() at the next time when Android gets control of the main thread (ie: when all your activity methods have returned). In any case, you can't determine when the service will be started or when onStartCommand() will be called. It is an asynchronous call, so you need to rely on a callback mechanism. This means that you need to write some kind of callback method that the service can call when it has done the work and wants to return the result to you.

There are various ways to do this. You could have the service send an Intent to your activity. You could have the service broadcast an Intent with the results. You could bind to the service and register a callback listener (see developer documentation for bound services). There are probably other ways too.

查看更多
登录 后发表回答