Service 服务
是一种应用组件,可长时间后台运行,不提供用户界面。如音乐播放器/下载程序。不能自己运行。
使用Service的方式:
(一)startService():
调用者和服务之间没有联系,即使调用者退出了,服务仍然进行;调用者(Activity)无法访问服务中的方法,因为不能自己new出来服务,new出来的就不是服务了,只是普通对象。
onCreate()->onStartCommand()->服务启动->onDestroy()。注意onCreate()只执行一次,Service实例只有一个。
1) 编写Service的子类或者间接子类;
2) 重写方法:onStartCommand()、onBind()、onCreate()、onDestroy();
onBind()方法返回null即可,所需操作写在onStartCommand()方法中。
3) 使用Intent启动Service,与启动其他Activity一样,方法换成startService(),类由OtherActivity换为Service子类。Intent同时可以向Service传递数据。
4) 在manifest文件中声明服务:<service android:name=”.Service”/>,与Activity同一级别。
5) 终止Service用方法stopService()。在setting-》application-》runningService中可以查看到服务正在运行。
6) int onStartCommand(Intent intent,int flag,int startId):startId为该服务唯一标识,类似身份证号。
(二)bindService():
调用者和服务绑定在一起,调用者一旦退出,服务也就终止;调用者可以访问服务中的方法(不能直接创建对象访问,要用下面代码介绍的办法)。
onCreate()->onBind()->onUnbind()->onDestroy()
BoundService允许其他组件(如Activity)绑定到这个Service上,可以发送请求,也可以接受请求,甚至进行进程间的通话。BoundService仅仅在服务于其他组件时存在,不能独自无限期的在后台运行。
如何创建BindService:
当创建一个能提供绑定功能的服务时,我们必须提供一个IBinder对象,客户端能使用该对象与服务进行交互。IBinder对象创建的三种方式:(参见dev->Service->BoundServices)
1) 继承Binder类,步骤如下:
a. 在Service类中,定义Binder子类MyBinder,在其中定义用于返回BoundService对象的getService()方法。
b. 在Service类中,定义MyBinder对象,并在onBind()方法中返回该对象。
c. 在Service类中,可以定义其他公有方法,以便将来被Service对象调用。
a. 在Activity类中,定义ServiceConnection接口的对象,重写onServiceConnected()方法和onServiceDisconnected()方法。
b. 在Activity类中,启动服务时执行bindService(intent,ServiceConnection,flag)方法,在服务连接成功时自动调用onServiceConnected(ComponentName,IBinder)方法,此方法的参数IBinder就是Service类中onBind()方法的返回值。因此可在此方法中得到Service对象,并可以调用Service类中定义的方法。onServiceDisconnected()方法很少调用,一般是当服务突然异常终止的时候调用。
参数flag取Context类中的常量:
Context.BIND_AUTO_CREATE:绑定时自动创建Service;最常用。
BIND_DEBUG_UNBIND:包含错误解绑时调试帮助。等等,查阅帮助文档。
(三)混合开启服务 解决调用者一旦退出退出,服务仍然开启
package com.example.shiyan5; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub System.out.println("绑定我的start服务"); return null; } @Override public void onCreate() { // TODO Auto-generated method stub System.out.println("创建我的start服务"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("启动我的start服务"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("销毁我的start服务"); super.onDestroy(); } }
package com.example.shiyan5; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class BindService extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub System.out.println("绑定我的Bind服务"); return new MyBinder1(); } @Override public void onCreate() { // TODO Auto-generated method stub System.out.println("创建我的Bind服务"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("启动我的Bind服务"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("销毁我的Bind服务"); super.onDestroy(); } public class MyBinder1 extends Binder{} }
package com.example.shiyan5; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class Music extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub System.out.println("Music——onBind"); return new MyBinder(); } public class MyBinder extends Binder{ public void callLast() { last(); } public void callPlay() { play(); } public void callNext() { next(); } public void callmusicstop() { musicstop(); } } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("准备音乐播放器"); } public void last(){ System.out.println("播放上一首"); } public void play(){ System.out.println("正在播放"); } public void next(){ System.out.println("播放下一首"); } public void musicstop(){ System.out.println("暂停播放"); } public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("启动我的Music服务"); return super.onStartCommand(intent, flags, startId); } public void onDestroy() { // TODO Auto-generated method stub System.out.println("销毁我的Bind服务"); super.onDestroy(); } }
package com.example.shiyan5; import com.example.shiyan5.Music.MyBinder; import android.os.Bundle; import android.os.IBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.view.View; public class MainActivity extends Activity { private MyConnection con; private MyBinder control; private MyConnection1 conn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); System.out.println("activity_onCreate"); } // start启动服务 public void start(View v){ Intent intent=new Intent(this,MyService.class); startService(intent); System.out.println("开始服务按钮"); } public void closes(View v){ Intent intent=new Intent(this,MyService.class); stopService(intent); System.out.println("停止服务按钮"); } //绑定Service服务 public void bindStart(View v){ Intent service1=new Intent(this,BindService.class); conn = new MyConnection1(); bindService(service1, conn, BIND_AUTO_CREATE); System.out.println("BInd_bindStart按钮"); } public void bindClose(View v){ unbindService(conn); System.out.println("BInd_unbindService按钮"); } private class MyConnection1 implements ServiceConnection{ @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { System.out.println("Bind_连接我的服务"); } @Override public void onServiceDisconnected(ComponentName arg0) { // TODO Auto-generated method stub System.out.println("BInd_onServiceDisconnected"); } } //音乐播放服务 public void start_music(View v){ System.out.println("开始音乐服务按钮"); Intent intent1=new Intent(this,Music.class); startService(intent1); } public void stop_music(View v){ System.out.println("停止服务按钮"); Intent intent2=new Intent(this,Music.class); stopService(intent2); } public void startbind_music(View v){ Intent service =new Intent(this,Music.class); con = new MyConnection(); bindService(service,con,BIND_AUTO_CREATE); System.out.println("BInd_bindStart按钮"); } public void destory_music(View v){ unbindService(con); System.out.println("销毁音乐服务Music按钮"); } public void last( View v){ control.callLast(); } public void play(View v){ control.callPlay(); } public void musicstop(View v){ control.callmusicstop(); } public void next(View v){ control.callNext();} private class MyConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { System.out.println("Music_onServiceconnected"); control = (MyBinder)arg1; } @Override public void onServiceDisconnected(ComponentName arg0) { // TODO Auto-generated method stub System.out.println("Music_onServiceDisconnected"); } } }
<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:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启服务" android:onClick="start" android:id="@+id/btn_s" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭服务" android:onClick="closes" android:id="@+id/btn_c" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启绑定服务" android:onClick="bindStart" android:id="@+id/btn_bs" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭绑定服务" android:onClick="bindClose" android:id="@+id/btn_bc" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动音乐服务" android:onClick="start_music" android:id="@+id/btn_sm" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止音乐服务" android:onClick="stop_music" android:id="@+id/btn_stm" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绑定音乐服务" android:onClick="startbind_music" android:id="@+id/btn_bm" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="销毁音乐服务" android:onClick="destory_music" android:id="@+id/btn_dm" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="前一首" android:onClick="last" android:id="@+id/btn_b" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放" android:onClick="play" android:id="@+id/btn_p" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暂停" android:onClick="musicstop" android:id="@+id/btn_m" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一首" android:onClick="next" android:id="@+id/btn_l" /> </LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.shiyan5" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.shiyan5.MainActivity" 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="com.example.shiyan5.MyService"></service> <service android:name="com.example.shiyan5.BindService"></service> <service android:name="com.example.shiyan5.Music"></service> </application> </manifest>