Service的运行是不可见的,如internet查找,处理数据,更新content PRovider,激活Intent和触发Notification。 1.创建Service
import android.app.Service;import android.content.Intent;import android.os.IBinder;public class MyService extends Service { @Override public void onCreate() { // TODO: Actions to perform when service is created. } @Override public IBinder onBind(Intent intent) { // TODO: Replace with service binding implementation. return null; }2.注册service
<service android:enabled="true" android:name=".MyService" Android:permission=“com.example.MY_SERVICE_PERMISSION”/>3.重写启动行为 当调用startService,就会调用onStartCommand(),Service实在UI线程中启动的,所以onStartCommand()也是在GUI线程中运行,所以需要创建一个新线程来后台执行。
/** * Listing 9-3: Overriding Service restart behavior */ @Override public int onStartCommand(Intent intent, int flags, int startId) { startBackgroundTask(intent, startId); return Service.START_STICKY; } private void startBackgroundTask(Intent intent, int startId) { // Start a background thread and begin the processing. backgroundExecution(); } /** * Listing 9-14: Moving processing to a background Thread */ //This method is called on the main GUI thread. private void backgroundExecution() { // This moves the time consuming Operation to a child thread. Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background"); thread.start(); } //Runnable that executes the background processing method. private Runnable doBackgroundThreadProcessing = new Runnable() { public void run() { backgroundThreadProcessing(); } }; //Method which does some processing in the background. private void backgroundThreadProcessing() { // [ ... Time consuming operations ... ] }4.启动service //显式启动service
private void explicitStart() { // Explicitly start My Service Intent intent = new Intent(this, MyService.class); // TODO Add extras if required. startService(intent); } //隐式启动service private void implicitStart() { // Implicitly start a music Service Intent intent = new Intent(MyMusicService.PLAY_ALBUM); intent.putExtra(MyMusicService.ALBUM_NAME_EXTRA, "United"); intent.putExtra(MyMusicService.ARTIST_NAME_EXTRA, "Pheonix"); startService(intent); }5.终止service
stopService(new Intent(this, MyService.class)); // Stop a service implicitly. Intent intent = new Intent(MyMusicService.PLAY_ALBUM); stopService(intent);自终止
stopSelf();6.Service绑定 用startService开启的服务,一旦开启之后,该service与activity就没有关系了。也就是说,activity很难调用到service上的方法,很难通过用户在activity上的操作去改变service的任务。同时,activity销毁也与service无关。activity销毁了之后service还在运行~ 如果是通过绑定service启动service那么就不存在这些问题了。
接下来就说说如何绑定Service, 还是跟平常一样新建一个Service,可以看到刚新建的Service里面有一个onBind方法,在Activity进行绑定Service之后会把onBind所返回的对象返回到onServiceConnected,我们只需要在该回调里接收所返回的对象就可以了。我们就是根据这个返回的对象来操作service里面的方法。因此我们先新建一个内部类,把将要调用的方法都写在这个内部类里面,这里我写了个log的方法作为示例。上面提到onBind会把一个对象返回到onServiceConnected里,所以我们把刚定义好的内部类的对象放到onBind里面,并且返回出去。
public IBinder onBind(Intent intent) { Log.e("bind","onBind"); return new MyBind(); } public class MyBind extends Binder{ public void logMessage(String msg){ Log.e("testlog",msg); } }我们可以看到onBind的返回值是IBinder,因此我们需要让新建的内部类实现Ibinder接口,但是我们会发现Ibinder接口实在有太多方法需要实现,这个时候我们可以选择继承一个默认的实现类Binder。 private class MyConn implements ServiceConnection{
@Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("bindLog","bind"); mybind= (MyService.MyBind) service; } @Override public void onServiceDisconnected(ComponentName name) { Log.e("bindLog","unbind"); } }执行绑定操作
private MyConn conn; Intent intent =new Intent(this,MyService.class); bindService(intent, conn, BIND_AUTO_CREATE);最后使用mybind调用service中的方法。 通过这种方式启动的service,如果activity销毁了,所绑定的service也随之销毁。 并且一旦绑定后,如果解绑该service那么该service也会销毁。
新闻热点
疑难解答