Android Service

Android Service

什么是service

service是一个可以在后台长时间运行而没有UI界面的组件。
service可由其他组件(如Activity)启动,service一旦被启动将在后台一直运行,即使启动service的组件已被销毁。
组件可以绑定到service,来与之交互,甚至是执行进程间通信 (IPC)。service可以处理网络事务/播放音乐/执行文件I/O等。

使用service的两种方式

  1. 启动service
    应用组件(如Activity)通过调用startService() 启动service。一旦启动,service即可在后台无限期运行,即使启动service的组件已被销毁也不受影响,除非手动停止service,已启动的service通常是执行单一操作,而且不会将结果返回给调用方。
  2. 绑定service
    应用组件通过调用bindService()绑定service。绑定service提供了一个组件-服务接口,允许组件与service进行交互、发送请求、获取结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。多个组件可以同时绑定到该service,在全部组件取消绑定后,该service即会被销毁。

继承service

使用Service要继承Service或继承它的子类IntentService。

启动Service

启动service使用startService(Intent intent)方法。
第一次调用startService()方法时,会执行onCreate()和onStartCommand()方法。再次调用startService()方法时,只会执行onStartCommand()方法。可以在service外部调用stopService()方法停止service,也可以在service内部用stopSelf()方法停止service。停止service时执行onDestory()方法。

绑定Service

绑定service时service的生命周期通常只在为其他组件服务时处于活动状态,不会无限期在后台运行,宿主(如Activity)解除绑定后,service就会被销毁。
使用方法:

  1. 在自己写的service子类中,定义一个Binder类的子类,提供一个获取service子类对象的方法。
  2. 在service子类的onBind()方法中,返回Binder子类的对象。
  3. 在service子类的onCreate()方法中,执行service该执行的任务。
  4. 在Activity中通过bindService()方法绑定service。
  5. 在Activity中创建ServiceConnection的对象,调用bindService()方法时使用。
  6. 创建ServiceConnection对象时,要重写该类的两个回调方法。onServiceConnected为绑定成功时的回调方法,在该方法中可以获取到Binder子类的对象,进而获取到service子类的对象。
  7. 通过service子类的对象,可以调用到service子类中定义的其他方法,达到Activity和Service交互的目的。
  8. Activity要在合适的时机执行unbindService()方法来解除与某个Service子类的绑定,解除绑定时,Service会执行onDestory()方法。
  9. 系统“绝对不会”在Activity取消绑定时调用创建ServiceConnection对象时重写的onServiceDisconnected()方法。该方法会在服务崩溃或被杀死导致的连接中断时被调用。
  10. 绑定Service这种Service的使用方式不会执行Service的onStartCommand()方法。
  11. 一个Activity多次绑定同一个service, service子类的onBind()方法只会执行一次。
  12. 多个Activity可以绑定到同一个service,当所有绑定全部解绑后,系统会销毁该service。未全部解绑时,即使调用stopService() 方法或 stopSelf() 方法也不会销毁该service。

绑定Service实例

package com.zejian.ipctest.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

public class LocalService extends Service{
    private final static String TAG = "wzj";
    private int count;
    private boolean quit;
    private Thread thread;
    private LocalBinder binder = new LocalBinder();

    /** Binder类的对象会返回给Activity */
    public class LocalBinder extends Binder {
        // Activity通过binder对象调用此方法获取service对象
        LocalService getService() {
            return LocalService.this;
        }
    }

    /** 把Binder对象给Activity */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!quit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        });
        thread.start();
    }

    /** Activity通过service对象调用service此方法 */
    public int getCount(){
        return count;
    }

     @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        this.quit = true;
        super.onDestroy();
    }
}
package com.zejian.ipctest.service;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.zejian.ipctest.R;

public class BindActivity extends Activity {
    protected static final String TAG = "wzj";
    Button btnBind;
    Button btnUnBind;
    Button btnGetDatas;
    private ServiceConnection conn;
    private LocalService mService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind);
        btnBind = (Button) findViewById(R.id.BindService);
        btnUnBind = (Button) findViewById(R.id.unBindService);
        btnGetDatas = (Button) findViewById(R.id.getServiceDatas);
        btnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//准备intent
            	Intent intent = new Intent(this, LocalService.class);
                //绑定service
                bindService(intent, conn, Service.BIND_AUTO_CREATE);
            }
        });
        btnUnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 解除绑定service
                if(mService!=null) {
                    mService = null;
                    unbindService(conn);
                }
            }
        });
        btnGetDatas.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mService != null) {
                	//Activity调用service中的方法
                    Log.d(TAG, "从服务端获取数据:" + mService.getCount());
                } else {
                    Log.d(TAG, "还没绑定呢,先绑定,无法从服务端获取数据");
                }
            }
        });

        conn = new ServiceConnection() {
            /**
             * 绑定service成功时被回调,在这个方法中获取service中onBind()方法返回的IBinder对象
             */
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
                mService = binder.getService();
            }
            /**
             * 在服务崩溃或被杀死导致的连接中断时被调用
             */
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mService=null;
            }
        };
    }
}

一个Service既被启动又被绑定

启动service的优先级比绑定service的优先级高。

  • 先绑定service后启动service
    如果Service先以绑定状态运行,再以启动状态运行,那么绑定service状态将会转为启动service运行的状态,这时如果之前绑定的宿主被销毁了,也不会影响service的运行,service还是会一直运行下去,直至手动停止service或者内存不足时才会销毁该服务。
  • 先启动service后绑定service
    如果Service先以启动状态运行,然后再以绑定状态运行,当前启动服务并不会转为绑定服务,但是还是会与宿主绑定,只是即使宿主解除绑定后,service依然按启动service的生命周期在后台运行,直到有Context调用了stopService()或是service本身调用了stopSelf()方法抑或内存不足时才会销毁服务。

IntentService

  1. 本质是一种特殊的Service,继承自Service并且本身就是一个抽象类。
  2. 用于在后台执行耗时的异步任务,当任务完成后会自动停止。
  3. 拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务。
  4. 内部通过HandlerThread和Handler实现异步操作。
  5. 创建IntentService时,只需重写onHandleIntent()方法和构造方法(传递一个线程名称的字符串),onHandleIntent()为异步方法,可以执行耗时操作。

注意事项

  1. Service类中onStartCommand()内直接调用Service的onStart()方法。
  2. Service在其托管进程的主线程中运行,它既不创建自己的线程,也不在单独的进程中运行(除非另行指定)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值