Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

android - Set a Listener in a Service-based Class

Hy i have a problem to set the ServiceUpdateUIListener in the service to update the UI. It's wrong to make a new Service object and set there the listener and put it in an intent.

Code source is at http://developerlife.com/tutorials/?p=356 there i can't find how the set the listener and start the service right.

Calling:

TimerService service = new TimerService();
                TimerService.setUpdateListener(new ServiceUpdateUIListener() {

                    @Override
                    public void updateUI(String time) {
                        clock.setText(time);

                    }
                });

                Intent i  = new Intent(Timer.this,service.class); //service cannot be resolved to a type
                i.putExtra("ms", ms);
                startService(i);  

Service:

 public class TimerService extends Service{

        CountDownTimer timer;
        Chronometer clock;
        public static ServiceUpdateUIListener UI_UPDATE_LISTENER;

        @Override
        public IBinder onBind(Intent intent) {

            return null;
        }
        @Override
        public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            int ms = intent.getIntExtra("ms", 0);

            timer = new  CountDownTimer(ms,1000){
                @Override
                public void onTick(long millisUntilFinished) {

                    int seconds = (int) (millisUntilFinished / 1000) % 60 ;
                    int minutes = (int) ((millisUntilFinished / (1000*60)) % 60);
                    int hours   = (int) ((millisUntilFinished / (1000*60*60)) % 24);

                    clock.setText( String.format("%02d:%02d:%02d", hours,minutes,seconds));
                    Log.e("Timer", String.valueOf(millisUntilFinished));

                }

                @Override
                public void onFinish() {
                    // TODO Auto-generated method stub

                }
            }.start();
            super.onStart(intent, startId);
        }
        public static void setUpdateListener(ServiceUpdateUIListener l) {
             UI_UPDATE_LISTENER = l;

        }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Service documentation has fairly complete sample code for implementing a service in your app that another part of your app can bind to and make calls on:

http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

Just put your setUpdateListener() method on the Service, and call it once you get onServiceConnected() with the service.

So your code would be something like this:

public interface UpdateListener {
    public void onUpdate(long value);
}

class LocalService {
    // Like in the Service sample code, plus:

    public static String ACTION_START = "com.mypackage.START";

    private final ArrayList<UpdateListener> mListeners
            = new ArrayList<UpdateListener>();
    private final Handler mHandler = new Handler();

    private long mTick = 0;

    private final Runnable mTickRunnable = new Runnable() {
        public void run() {
            mTick++;
            sendUpdate(mTick);
            mHandler.postDelayed(mTickRunnable, 1000);
        }
    }

    public void registerListener(UpdateListener listener) {
        mListeners.add(listener);
    }

    public void unregisterListener(UpdateListener listener) {
        mListeners.remove(listener);
    }

    private void sendUpdate(long value) {
        for (int i=mListeners.size()-1; i>=0; i--) {
            mListeners.get(i).onUpdate(value);
        }
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (ACTION_START.equals(intent.getAction()) {
            mTick = 0;
            mHandler.removeCallbacks(mTickRunnable);
            mHandler.post(mTickRunnable);
        }
        return START_STICKY;
    }

    public void onDestroy() {
        mHandler.removeCallbacks(mTickRunnable);
    }

Now you can start the service to get it to start counting, and anyone can bind to it to register a listener to receive callbacks as it counts.

It is really hard though to answer your question very well because you aren't really saying what you actually want to accomplish. There are a lot of ways to use services, either starting or binding or mixing the two together, depending on exactly what you want to accomplish.

Now you can implement your client code again based on the sample:

public class SomeActivity extends Activity implements UpdateListener {
    private LocalService mBoundService;

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((LocalService.LocalBinder)service).getService();
            mBoundService.registerListener(this);
        }

        public void onServiceDisconnected(ComponentName className) {
            mBoundService = null;
        }
    };

    void doBindService() {
        bindService(new Intent(Binding.this, 
                LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }

    void doUnbindService() {
        if (mIsBound) {
            if (mBoundService != null) {
                mBoundService.unregisterListener(this);
            }
            unbindService(mConnection);
            mIsBound = false;
        }
    }

    protected void onDestroy() {
        super.onDestroy();
        doUnbindService();
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...