用绑定服务来实现放歌的功能

绑定服务—与调用者同生死的服务

简单来讲相比于普通service,绑定服务就显得专情多了。。先来一个布局文件

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.musicplayer.MainActivity" >
    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text_tv"
        android:layout_centerHorizontal="true"
        android:onClick="bind"
        android:layout_marginTop="63dp"
        android:text="绑定" />

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="26dp"
        android:onClick="unbind"
        android:text="解除绑定" />

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button2"
        android:layout_below="@+id/button2"
        android:layout_marginTop="23dp"
        android:onClick="playmusic"
        android:text="播放音乐" />

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button3"
        android:layout_below="@+id/button3"
        android:layout_marginTop="28dp"
        android:onClick="stopmusic"
        android:text="停止音乐" />

    <TextView
        android:id="@+id/text_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp"
        android:text="界面" />

</RelativeLayout>

MainActivity的代码如下

public class MainActivity extends Activity {
//  private MyBinder myBinder;//声明服务的代理对象
    private MyBinder myBinder;
    private boolean bindFlag=false;

    private static final String TAG = "BindActivity";
    private ServiceConnection conn=new ServiceConnection() {
        //当调用者与服务连接不成功,则回调该方法, 当连接出现异常会回调该方法,假如调用者自己实现的解绑操作,则不会回调该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v(TAG,"onServiceDisconnected");
            bindFlag=false;
        }
        /**当调用者与服务连接成功,则回调该方法
         * ComponentName: 调用者的组件名
         * IBinder: 实现了IBinder接口的对象 ,当要绑定的服务成功回调onBind()方法,则表示绑定成功,即onBind的返回值作为该方法的输入参数
         *  通过该IBinder参数来获取服务的实例或者是代理对象
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.v(TAG,"onServiceConnected");
            myBinder=(MyBinder) service; //获取代理对象
        //  myBinder=(IService) service; //获取代理对象
            bindFlag=true;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        Log.v(TAG,"onCreate");
    }

    //绑定服务
        public void bind(View v){
            Log.v(TAG,"bind");
            Intent intent=new Intent(this, BindMusic.class);
            /**绑定服务
             * Intent :要绑定的服务的意图描述 
             * ServiceConnection : 服务连接接口, 调用者和服务 通过这个接口实现通信的,即是调用者与被调用者的桥梁
             *                    通过这个接口,可以获取服务的实例或者服务的代理对象
             * BIND_AUTO_CREATE: 绑定自动创建
             */
            this.bindService(intent, conn, Context.BIND_AUTO_CREATE);
        }

        //解绑服务
        public void unbind(View v){
            Log.v(TAG,"unbind");
            this.unbindService(conn);
            bindFlag=false;
//          conn=null;
        }
        //播放音乐
        public void playmusic(View v){
            Log.v(TAG,"playMusic");
            if(myBinder!=null){
                myBinder.playMusic();
            }
        }
        //停止音乐
        public void stopmusic(View v){
            Log.v(TAG,"stopMusic");
            if(myBinder!=null){
                myBinder.stopMusic();
            }

        }

        @Override
        protected void onDestroy() {
//          if(conn!=null){
//              unbindService(conn);
//          }
            if(bindFlag){
                this.unbindService(conn);
            }

            super.onDestroy();
        }

}

绑定服务的代码


public class BindMusic extends Service {
    private static final String TAG = "BindMusic";
    private MediaPlayer player;

    // 返回Ibinder对象(把服务的实例或者代理的对象通过Ibinder返回给调用者)
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Log.v(TAG, "onBind");
        return new MyBinder();
    }

    public void closeMusic() {
        // TODO Auto-generated method stub
        if (player != null) {
            player.stop();
            player.release();
            player = null;
        }
    }

    public void startMusic() {
        // TODO Auto-generated method stub
        if (player == null) {
            player = new MediaPlayer();
            try {
                player.setDataSource(
                        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath()
                                + "/imissyou.mp3");
                player.prepare();// 缓冲
            } catch (Exception e) {
                // TODO: handle exception
            }

        }
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        Log.v(TAG, "oncreat");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.v(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        Log.v(TAG, "onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        Log.v(TAG, "onDestroy");
        if (player != null) {
            player.stop();
            player.release();// 释放资源
            player = null;
        }
        super.onDestroy();
    }

    // 返回服务的代理类 ,通过该代理来对外暴露服务的相应方法
    public class MyBinder extends Binder {
        private static final String TAG = "MyBinder";

        // 对外暴露 播放音乐的方法
        public void playMusic() {
            Log.v(TAG, "playMusic+IService");
            startMusic();
        }

        // 对外暴露停止音乐的方法
        public void stopMusic() {
            Log.v(TAG, "stopMusic+IService");
            closeMusic();
        }
    }
}

注意要在配置文件中注册绑定服务

  <service android:name=".BindMusic">

        </service>

面向接口的代理的实现
先定义两个接口Iservice和Iservice2

public interface Iservice {
    public void playMusic();
    public void stopMusic() ;
}
public interface Iservice2 {
    public void playMusic();
    public void stopMusic() ;
    public void psuseMusic();
}

内部类实现接口的方法

public class MyBinder extends Binder implements Iservice{
        private static final String TAG = "MyBinder";

        // 对外暴露 播放音乐的方法
        public void playMusic() {
            Log.v(TAG, "playMusic+IService");
            startMusic();
        }

        // 对外暴露停止音乐的方法
        public void stopMusic() {
            Log.v(TAG, "stopMusic+IService");
            closeMusic();
        }


    }

效果如下

我们来看打印信息
绑定--播放--暂停---解除绑定

posted @ 2016-04-28 20:59  Tesi1a  阅读(188)  评论(0编辑  收藏  举报