android Service之二:和Activity交互的本地服务

如果Service和Activity之间需要传递参数或者方法调用。需要使用bind和unbind方法。

具体做法是,服务类增加接口(非必须,在调用类里也可以用下例中的ServiceBinder去强转(把ServiceBinder改成public),比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类(Binder继承自IBander)并实现ICountService接口。还有,就是要实现Service的onBind方法,不能只传回一个null了。

这是新建立的接口代码:

  
  
package com.easymorse; public interface ICountService { public abstract int getCount(); }

修改后的CountService代码:

  
  
package com.easymorse; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class CountService extends Service { private boolean threadDisable; private int count; private ServiceBinder serviceBinder = new ServiceBinder(); public class ServiceBinder extends Binder implements ICountService{ @Override public int getCount() { return count; } } @Override public IBinder onBind(Intent intent) { return serviceBinder; } @Override public void onCreate() { super .onCreate(); new Thread( new Runnable() { @Override public void run() { while ( ! threadDisable) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { } count ++ ; Log.v( " CountService " , " Count is " + count); } } }).start(); } @Override public void onDestroy() { super .onDestroy(); this .threadDisable = true ; Log.v( " CountService " , " on destroy " ); } /* (non-Javadoc) * @see com.easymorse.ICountService#getCount() */ public int getCount() { return count; } }

服务的注册也要做改动,AndroidManifest.xml文件:

  
  
<? xml version="1.0" encoding="utf-8" ?> < manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="com.easymorse" android:versionCode ="1" android:versionName ="1.0" > < application android:icon ="@drawable/icon" android:label ="@string/app_name" > < activity android:name =".LocalServiceDemoActivity" android:label ="@string/app_name" > < intent-filter > < action android:name ="android.intent.action.MAIN" /> < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < service android:name ="CountService" > < intent-filter > < action android:name ="com.easymorse.CountService" /> </ intent-filter > </ service > </ application > < uses-sdk android:minSdkVersion ="3" /> </ manifest >

Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。

package com.easymorse;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class LocalServiceDemoActivity extends Activity {

    private ServiceConnection serviceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            countService = (ICountService) service;
            Log.v("CountService", "on serivce connected, count is "
                    + countService.getCount());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            countService = null;
        }

    };

    private ICountService countService;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.bindService(new Intent("com.easymorse.CountService"),
                this.serviceConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.unbindService(serviceConnection);
    }
}


注意以下几点:

1.bind后,activity和service就联系在一起了,activitydestory后,service如果没有调用unbind,也会自动unbind

2.bindservice用stopservice是停不了的

3.多次bindservice,只有第一次调用oncreate和onbind,后面只会回调serviceConnection的onServiceConnected,传回的是同一个IBinder对象

bindService(mIntent,mSerCon,BIND_AUTO_CREATE);

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        bindService(mIntent,mSerCon,BIND_AUTO_CREATE);
    }
}, 4000);
上例中,即使两次bind传入的serviceconnection对象不一样,回调得到的IBinder对象也是同一个


4.bind多次,传入的serviceconnection对象一样,则只要unbind一次就可以了,如果传入的serviceconnetion不一样,要unbind多次

mIntent = new Intent("com.test.myservice");
mSerCon = new MySevConnect();
mSerCon2 = new MySevConnect();
bindService(mIntent,mSerCon,BIND_AUTO_CREATE);

bindService(mIntent,mSerCon2,BIND_AUTO_CREATE);

unbindService(mSerCon);
上面两个connection对象不一样,unbind一次后,service还正常运行,需要unbind两次或退出activity才停止

如果两个bind都传入mSerCon,则只要unbind一次就ok了


5.如果一个服务需要长期运行,又需要跟activity交互,这是要就要同时调用start和bind了:

如果一个Service又被启动又被绑定,则该Service会一直在后台运行。首先不管如何调用,onCreate始终只会调用一次。对应startService调用多少次,Service的onStartcommand方法便会调用多少次。Service的终止,需要unbindService和stopService同时调用才行。不管startService与bindService的调用顺序,如果先调用unbindService,此时服务不会自动终止,再调用stopService之后,服务才会终止;如果先调用stopService,此时服务也不会终止,而再调用unbindService或者之前调用bindService的Context不存在了(如Activity被finish的时候)之后,服务才会自动停止。

那么,什么情况下既使用startService,又使用bindService呢?

如果你只是想要启动一个后台服务长期进行某项任务,那么使用startService便可以了。如果你还想要与正在运行的Service取得联系,那么有两种方法:一种是使用broadcast,另一种是使用bindService。前者的缺点是如果交流较为频繁,容易造成性能上的问题,而后者则没有这些问题。因此,这种情况就需要startService和bindService一起使用了






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值