一、先简单首先回顾一下Service的一些问题
1、为什么使用Service?
答:对于一些需要长时间才可执行完毕的操作放在Activity里不太合适,因为Activity关闭后导致操作不能再继续,但后台服务可以持续运行。
2、bindService和startService的区别?
答:1)两者创建的service的生命周期不同
2)startService启动的服务不能返回service的实例,bindService的可以
3、为什么不直接使用new XxxxService来创建服务?
答:在执行startService或者bindService时,android会把会启动的服务进行记录(未做深入研究),以确保拥有后台服务的进程具有较高的优先级,所以要使用startService或者bindService来创建服务。new XxxxService只是创建了一个服务类的实例,而不是一个服务。
4、为什么onServiceDisconnected一直未被调用到?
答:unbindService并不会导致onServieDisconnected被调用,只有在服务被系统销毁的时候才会被调用。
5、可以在一个应用中使用startService跨进程启动另外一个进程的服务吗?
答:可以,需要设置目标进程的包名,可以使用如下代码或者setPackage(未测试)
1 2 3 |
Intent intent = new Intent(); intent.setClassName("com.zht.car.testservice", "com.zht.car.testservice.MyTestService"); startService(intent); |
6、既然可以跨进程调用startService那为什么还要使用aidl?
答:startService只能启动另外进程的服务,最多还可以通过intent传入一些参数,但是不能从对方进程返回数据,所以如果跨进程通讯aidl还是很有必要的。
二、bindService的开发步骤简述
1、创建一个Service,比如本例中为MyTestService
2、在Service中定义一个Binder的子类MyServiceBinder,后面用来返回MyTestService的实例(见一、3为什么不能直接new MyTestService() )
3、定义并实例化一个MyServiceBinder对象,用来在Service的onBind函数中返回给调用者
4、在Service的onBind函数中返回MyServiceBinder实例对象,android sdk会通过各种调用将这个对象传到ServiceConnection的onServiceConnected
5、在Activity中定义一个MyTestService对象
6、在Activity中执行bindService
7、在Activity中实例化一个ServiceConnection对象
8、在ServiceConnection对象的onServiceConnected回调函数中,将参数中的IBinder对象强制转换为Service中定义的Binder子类(MyServiceBinder)对象
9、通过强制Binder子类对象的方法获取MyTestService实例,至此就得到这个Service的实例了
10、绑定状态的控制,通过一个boolean类型的变量来控制,以及其他的回调函数的设置
三、时序图
四、代码
1、Service的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package com.zht.car.testservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Handler; import android.os.IBinder; public class MyTestService extends Service { private MyServiceBinder mMyServiceBinder = new MyServiceBinder(); private OnWeightChangeListener mOnWeightChangeListener; private int mWeight = 20; public MyTestService() { } @Override public IBinder onBind(Intent intent) { new Handler().postDelayed(new Runnable() { @Override public void run() { mWeight = mWeight * 2; if(mOnWeightChangeListener != null){ mOnWeightChangeListener.onWeightChange(mWeight); } } }, 1000); return mMyServiceBinder; } class MyServiceBinder extends Binder { MyTestService getService(){ return MyTestService.this; } } public int getWeight() { return mWeight; } public void setOnWeightChangeListener(OnWeightChangeListener onWeightChangeListener) { mOnWeightChangeListener = onWeightChangeListener; } public interface OnWeightChangeListener { public void onWeightChange(int weight); } } |
2、Activity代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
package com.zht.car.testservice; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends AppCompatActivity { private MyTestService mMyTestService; private String LOG_TAG = "MainActivity"; private boolean mServiceBinded = false; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { MyTestService.MyServiceBinder binder = (MyTestService.MyServiceBinder) service; mMyTestService = binder.getService(); mMyTestService.setOnWeightChangeListener(new MyTestService.OnWeightChangeListener() { @Override public void onWeightChange(int weight) { Log.d(LOG_TAG, "Weight changed: " + mMyTestService.getWeight()); } }); mServiceBinded = true; Log.d(LOG_TAG, "Service connected."); Log.d(LOG_TAG, "weight: " + mMyTestService.getWeight()); } @Override public void onServiceDisconnected(ComponentName name) { Log.d(LOG_TAG, "Service disconnected."); mServiceBinded = false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onDestroy() { if(mServiceBinded) { unbindService(mServiceConnection); } super.onDestroy(); } public void onBindServiceClick(View view) { if(mServiceBinded){ return; } Intent intent = new Intent(this, MyTestService.class); bindService(intent, mServiceConnection, Service.BIND_AUTO_CREATE); } public void onUnbindServiceClick(View view) { if(!mServiceBinded) { return; } unbindService(mServiceConnection); mServiceBinded = false; } } |
Sorry, the comment form is closed at this time.