Android Service 的使用(二)----Service的绑定使用

来源:互联网 发布:网络教育没有按时毕业 编辑:程序博客网 时间:2024/04/29 20:14

上次我们留下一个疑问,其实问题的答案很简单,就是Service只在第一建立时才会创建onCreate()方法,一旦Service已经建立成功,当程序再次调用时不在执行onCreate()方法,而直接执行onStartCommand(),也就是说onStartCommand()可以不止一次被调用。顺带说一句public int onStartCommand(Intent intent, int flags, int startId)这个方法有个参数startId,这个就是代表service运行的次数,换句话理解就是执行一次onStartCommand()这个数就会自动加1。

下面总结一下,Service的绑定使用。

1. 首先还是建立一个Service,Service的建立请参阅上一篇文章,这里就不在赘述了。

不过这里onBind()方法不再返回一个空,而是返回一个Ibinder的接口给调用的接口。

public IBinder onBind(Intent intent) {
        Log.d("zinc",">>>>>>>>>service is onbind<<<<<<<<<<<<");
        // TODO Auto-generated method stub        
        return new MyBinder();
    }

在建立一个内部类MyBinder()继承Binder

public class MyBinder extends Binder {       
        public  MyService getMyService() {
            return MyService.this;
        }
    }

2. 在需要的Context中建立SerivceConnect接口,这里我用一个activity和service进行绑定。activity的完整代码如下:

public class BindServiceTestActivity extends Activity implements OnClickListener {
    private Button startButton;
    private Button stopButton;
    
    private MyService myService;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        startButton= (Button)findViewById(R.id.startbutton);
        stopButton= (Button)findViewById(R.id.stopbutton);       
        
        startButton.setOnClickListener(this);
        stopButton.setOnClickListener(this);
    }
          
    public void onClick(View v) {         
        switch(v.getId()){
            case R.id.startbutton:
                Intent intent = new Intent();
                intent.setClass(this, MyService.class);
                bindService(intent,conn,Service.BIND_AUTO_CREATE);
                break;
            case R.id.stopbutton:
                unbindService(conn);
                break;
            default:
                break;
        }    
    }  
    
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        myService = null;
    }

    private ServiceConnection conn = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            Log.d("zinc",">>>>>>>>>>>>service has already bind with activity<<<<<<<<<<<");            

            myService = ((MyService.MyBinder)service).getMyService();

            //如果myService不为null,去执行service中的justest()方法;

            if (myService!=null){
                Log.d("zinc",">>>>>>>>>>myService is not null<<<<<<<<");
                myService.justTest();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            Log.d("zinc",">>>>>>>>>>>>service has already unbind with activity<<<<<<<<<<<");
        }       

    };

}

onServiceConnected(ComponentName name, IBinder service) 这个方法是context绑定service后会回调到这里,所以我们打个log看看activity有没有和service绑定成功。

蓝色字体的一行表示返回的IBinder类型转换,再去获取MyService的实例。再给出Service的代码这样就一目了然了:

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        Log.d("zinc",">>>>>>>>>service is onbind<<<<<<<<<<<<");
        // TODO Auto-generated method stub        
        return new MyBinder();
    }
        
    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        return super.onUnbind(intent);
    }

    public class MyBinder extends Binder {
        
        public  MyService getMyService() {
            return MyService.this;
        }
    }
    
    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.d("zinc",">>>>>>>>>>service onCreate()<<<<<<<<<<<<");
        Toast.makeText(MyService.this, "服务已建立", Toast.LENGTH_LONG).show();        
    }    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.d("zinc",">>>>>>>>>>service onStartCommand()<<<<<<<<<<<<<");
        Toast.makeText(MyService.this, "服务已启动", Toast.LENGTH_LONG).show();
        return super.onStartCommand(intent, flags, startId);
        
    }
    
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Log.d("zinc",">>>>>>>>>>service onDestory()<<<<<<<<<<<<");
        Toast.makeText(MyService.this, "服务已停止", Toast.LENGTH_LONG).show();
    }
    
    public void justTest(){
        Log.d("zinc",">>>>>>>>>justTest()<<<<<<<<<<");
    }
}

有兴趣的朋友可以把程序调试一遍,你会发现:绑定service后,不会执行service的onStartCommand() 方法,只会执行onCreat()方法;当然可以用startService去启动Service。

最后有一点也很重要:红色字体的一行,当activity销毁时,记得把myService这个引用重新赋值为null;我也是听了陈老师的话才有点明白。因为myService实际上是MyService的一个内部类MyBinder获取的引用,如果myService最后在activity中不处理为null的话,那这个引用始终释放不了,最终Service无法真正的释放。虽然从log总看到service好像走到onDestroy,但是因为内部引用始终占据内存空间,java的回收机制不会去处理外部类的回收。



原创粉丝点击