Android四大组件之Service

来源:互联网 发布:保柏 知乎 编辑:程序博客网 时间:2024/06/03 13:46

Service:是一个可以在后台执行长时间运行操作而不使用用户界面的Android应用组件。启动Service有两种方式:startServie和bindService。通过startService开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在 。通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 (若该service仅与该调用者绑定,那么该调用者被销毁,那么该service也被销毁;若该service与多个调用者绑定,那么当所有调用者与该service解除绑定,该service被销毁)。
一、startService的方式启动Service,其生命周期为:onCreate–>onStartCommand(android2.0以前,为onStart)–>onDestroy.
下面为利用Service播放音乐的demo
MainActivity的xml文件,里面有播放音乐、停止播放和停止服务三个按钮

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button        android:id="@+id/play_musi"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="开始播放" />    <Button        android:id="@+id/stop_music"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="停止播放播放" />    <Button        android:id="@+id/stop_service"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="停止服务" /></LinearLayout>

MainActivity Java文件,当多次调用startService,Service的onCreate方法只会被调用一次,onStartCommand方法被多次调用,所以在onStartCommand实现播发和停止播放音乐的逻辑

package com.example.servicetest;import android.R.integer;import android.net.Uri;import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {    private Intent intent;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button play_music = (Button) findViewById(R.id.play_musi);        Button stop_music = (Button) findViewById(R.id.stop_music);        Button stop_service = (Button) findViewById(R.id.stop_service);        intent = new Intent();        intent.setClass(this, MusicService.class);        play_music.setOnClickListener(this);        stop_music.setOnClickListener(this);        stop_service.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.play_musi:            LogUtil.d("播放音乐");            intent.putExtra("msg", 0);            intent.putExtra("musicName", "music.mp3");            startService(intent);            break;        case R.id.stop_music:            LogUtil.d("停止播放音乐");            intent.putExtra("msg", 1);            startService(intent);            break;        case R.id.stop_service:            LogUtil.d("停止服务");            stopService(intent);            break;        default:            break;        }    }}

用于播放音乐的Service

package com.example.servicetest;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import android.app.Service;import android.content.Intent;import android.content.res.AssetFileDescriptor;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.IBinder;public class MusicService extends Service {    private MediaPlayer mediaPlayer; // 媒体播放器对象    @Override    public IBinder onBind(Intent arg0) {        return null;    }    @Override    public void onCreate() {        super.onCreate();        mediaPlayer = new MediaPlayer();        LogUtil.d("onCreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        int msg = intent.getIntExtra("msg", -1);        String musicName = intent.getStringExtra("musicName");        LogUtil.d("onStartCommand" + "msg: " + msg + " musicName: " + musicName);        if (msg == 0) {            play(musicName);        }        if (msg == 1) {            stop();        }        return super.onStartCommand(intent, flags, startId);    }    private void play(String musicName) {        try {            LogUtil.d("play");            mediaPlayer.reset();// 把各项参数恢复到初始状态            AssetFileDescriptor fileDescriptor = getAssets()                    .openFd(musicName);            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);            mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),            fileDescriptor.getStartOffset(),            fileDescriptor.getLength());            mediaPlayer.prepare();            mediaPlayer.start();        } catch (Exception e) {            LogUtil.d("播放失败:" + e.getMessage());            e.printStackTrace();        }    }    private void stop() {        if (mediaPlayer != null && mediaPlayer.isPlaying()) {            mediaPlayer.pause();            LogUtil.d("stop");        }    }    @Override    public void onDestroy() {        LogUtil.d("onDestroy");        stop();        mediaPlayer = null;        super.onDestroy();    }}

二、bindService的方式启动Service,其生命周期为:onCreate–>onBind–>Service运行–>调用者unbindService或调用者被销毁–>–>onUnbind–>onDestroy.Service中还有一个onRebind方法,那么它何时被调用呢?如果调用者同时startService和bindService,当调用者和service解除绑定后,并且onUnbind返回为true(默认情况下,onUnbind方法返回return super.onUnbind(intent);而super.onUnbind(intent)为false,所以要手动返回为true),当调用者再次绑定Service时,onRebind会被调用。
以下bindService的demo中,MyService继承于Service,有个继承于Binder的内部类,并定义了MyServiBce方法,目的是通过MyBinder返回MyService的实例。

package com.example.bindservice;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class MyService extends Service{    private MyBinder mBinder = new MyBinder();    @Override    public void onCreate() {        super.onCreate();        LogUtil.d("onCreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        LogUtil.d("onStartCommand");        return super.onStartCommand(intent, flags, startId);    }    @Override    public boolean onUnbind(Intent intent) {        LogUtil.d("onUnbind");        boolean re = super.onUnbind(intent);        LogUtil.d("onUnbind默认返回: " + re);        //return super.onUnbind(intent);        return true;    }    @Override    public void onRebind(Intent intent) {        LogUtil.d("onRebind");        super.onRebind(intent);    }    @Override    public IBinder onBind(Intent arg0) {        LogUtil.d("onBind");        return mBinder;    }    public class MyBinder extends Binder{        public MyService getService(){            //返回serive实例            return MyService.this;        }    }    public int sum(int a,int b){        return a + b;    }    @Override    public void onDestroy() {        LogUtil.d("onDestroy");        super.onDestroy();    }}

MainActivity的java文件,其通过ServiceConnection和Service通信,如调用Service中的sum方法

package com.example.bindservice;import android.os.Bundle;import android.os.IBinder;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.util.Log;import android.view.Menu;import android.view.View;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void bindMyService(View v) {        LogUtil.d("绑定服务");        Intent intent = new Intent();        intent.setClass(this, MyService.class);        //startService(intent);        bindService(intent, conn, Context.BIND_AUTO_CREATE);    }    public void unbindMyService(View v) {        LogUtil.d("解除绑定服务");        unbindService(conn);    }    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName arg0, IBinder binder) {            MyService myService = ((MyService.MyBinder) binder).getService();            int sum = myService.sum(1, 2);            LogUtil.d("和: " + sum);        }        @Override        public void onServiceDisconnected(ComponentName arg0) {        }    };}

startService完整demo
bindService的完整demo

1 0
原创粉丝点击