在基于服务的类中设置监听器

tes*_*123 4 android android-service

我有一个问题是在服务中设置ServiceUpdateUIListener以更新UI.制作一个新的Service对象并在那里设置监听器并将其置于intent中是错误的.

代码源是在http://developerlife.com/tutorials/?p=356那里我找不到如何设置监听器并启动服务.

呼叫:

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);  
Run Code Online (Sandbox Code Playgroud)

服务:

 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;

        }
Run Code Online (Sandbox Code Playgroud)

hac*_*bod 24

服务文档包含相当完整的示例代码,用于在您的应用中实现服务的另一部分可以绑定并进行调用:

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

只需将您的setUpdateListener()方法放在Service上,并在使用该服务获得ServiceConnected()后调用它.

所以你的代码是这样的:

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);
    }
Run Code Online (Sandbox Code Playgroud)

现在你可以启动服务让它开始计数,任何人都可以绑定它来注册一个监听器来接收回调计数.

虽然很难回答你的问题,但你并没有真正说出你真正想要完成的事情.有很多方法可以使用服务,根据您想要完成的内容,启动或绑定或混合两者.

现在,您可以根据示例再次实现客户端代码:

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();
    }
Run Code Online (Sandbox Code Playgroud)


MrJ*_*Jre 2

我不知道你到底想要什么,但这不是这样做的方法。看来你混淆了很多事情。

在我看来,教程本身就是一个坏例子,在服务中保留对活动的静态引用在我看来是不好的做法;您可以使用绑定将您的服务绑定到活动,或者如果您不想,您可以传递意图。

据我所知,像您一样实例化服务并在其上设置侦听器是行不通的。您在 startService() 调用中收到错误,因为服务实例显然不是一个类;你应该使用TimerService.class。在您的服务中,您有一个 onStart(); onStart() 是一个已弃用的函数,您应该使用 onStartCommand() 代替。

现在,如果您有一个想要显示时钟的活动,您当然不需要也不希望服务直接更新其 UI,但如果您希望服务为您计算新的时钟滴答声,只需调用startService(); 只要您的服务处于活动状态,发送新的启动服务意图将仅使用您发送的意图调用 onStartCommand() 。

如果您的时钟位于活动中,请在您的活动中设置一个广播接收器,并让您的服务广播您设置的广播接收器可以接收的意图,并传递新的时钟值。