现在的位置: 首页 > 综合 > 正文

Android Service中的startService和bindService

2013年12月01日 ⁄ 综合 ⁄ 共 3437字 ⁄ 字号 评论关闭

Service创建有两种方法:  startService或者bindService

服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
 
service中可以下载,但是你要保证在系统的规定crash时间内完成,否则,你就会阻塞UI.
为什么播放不会阻塞,应为MediaPlayer使用了Handler + Looper 去更新UI. public MediaPlayer() {
        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }
        /* Native setup requires a weak reference to our object.
         * It's easier to create it here than in C++.
         */
        native_setup(new WeakReference<MediaPlayer>(this));
    }
 
如何在Service里维护多线程处理操作呢?(如:多线程下载)
1.首先要维护好一个任务队列
在Android开发当中,很多情况都会遇到多线程的时候。需要开启一条线程完成单独的任务。当需要对子线程进行生命控制并且要与主线程进行交互时。
HandlerThread 与Future就是一种很好的机制。

Looper和HandlerThread 。 Android提供的线程都带有一个Looper。 looper可以帮助线程维护一个消息队列。 Android使用Looper机制才能接受消息和处理
计划任务。  HandlerThread中封装了Looper对象。可以通过getLooper方法获取一个Looper对象。
 
不管是主线程还是子线程,只要有Looper线程,其他的线程就可以向这个线程的消息队列中发送消息和计划任务,然后做相应的处理。

 
2.每个任务都是一个线程在处理,用Callable实现返回线程任务执行状态
Callable/Future Callable接口类似于Runnable接口。实现Callable接口和实现Runnale接口的类都是可以被其他线程执行的任务。

Callable和Runnable的区别如下:

  Callable定义的方法是call,而Runnable定义的方法是run。

  Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。

  Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。

Future 表示异步任务的结果。它提供了检查任务是否完成的方法,以等待任务完成。并得到任务执行结果。通过Future可以对任务的生命周期进行控制。取消任务,判断任务是否执行完成。获取任务执行完成的结果。
其实Future只是一个接口,在java6中,提供了一个FutureTask对Future进行封装。在Android中,在某些情景下,使用FutureTask并不是很方便。我们可以单独的重新设计Future和FutureTask。

Future.java:
 public interface Future<T>{
    public void cancel();  // 取消任务

    public boolean isCancelled();  // 判断任务是否已被取消

    public boolean isDone(); // 判断任务是否已完成

     public T get(); // 获取任务完成的结果

    public void waitDone(); // 等待完成
 }

创建一个任务完成时的事件监听类。
FutureListener.java

    public interface FutureListener<T>{
        public void onFutureDone(Future<T> future);
    }

FutureTask.java

 public class FutureTask<T> implements Runnable,Future<T>{
    private Callable<T> mCallable ;
    private FutureListener<T> mListener ;
    private boolean mIsDone ;
    private volatile boolean mIsCancelled ;
    private T mResult ;

    public FutureTask(Callable<T> callable,FutureListener<T> listener){
        this.mCallable = callable ;
        this.mListener = listener ;
    }
    public FutureTask(Callable<T> callable){
        this(callable,null);
     

    public void cancel(){
        mIsCancelled = true ;
    }
   
    public boolean isCancelled(){
        return mIsCancelled ;
    }
   
    public synchronized boolean isDone(){
        return mIsDone ;
    }

    public synchronized T get(){
        while(!mIsDone){
            try{
                wait();
            }catch(Exception e){}
                   
        }
        return mResult ;
    }

    public void waitDone(){
        get();
    }

    public void run(){
        t = null ;
        if(!mIsCancelled){
            try{
                t = mCallable.call();

抱歉!评论已关闭.