Android组件之 Service

一、Service初步了解

        Service是Android中四大组件之一,用来进行后台处理时间长的任务操作,可以避免Android的ANR。最为经典的使用场景是在音乐播放器中,使用Service可以使音乐在后台播放,即使我们离开播放器APP音乐也不会停止。Service+Notification+Broadcast Receive三者联合使用将会得到意想不到的用户体验。作为组件,Service需要在Manifirst.xml文件中进行注册。

       想要使用Service服务必须继承android.app.Service类,主要处理其中的以下方法:

public class MyStartService extends Service {
	
	public void onCreate() {
		super.onCreate();
	}
	
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}
	
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	public IBinder onBind(Intent intent) {
		return null;
	}

        public boolean onUnbind(Intent intent) {
               return super.onUnbind(intent);
        }

        public void onDestroy() {
		super.onDestroy();
	}

}



二、Service的两种启动方式

       1、startService():Context组件通过调用此方法可以启动一个Service,此时启动的服务不收Context组件的生命周期的影响。也就是说当启动服务的组件销毁后,服务依然存在。此时Service的生命周期相关的函数是onCreat()、onStart()、onStartCommand()、onDestory();

startService()开始服务:

stopService()停止服务:

当我们多次startService()时,onCreate()只会调用一次,而onStart()和onStartCommand()可以多次调用,不管调用多少次startService(),我们只需要使用一次stopService()就可以将服务销毁,以下是我们进行3次启动1次销毁的log日志:


      

        2、bindService():Context组件通过调用此方法可以绑定一个Service,当启动它的组件销毁时,其绑定的服务也会一起销毁,有种爱叫做不求同生,但愿同死的赶脚。在启动组件销毁前,我们必须要保证它与绑定的服务间要有解绑动作,不然Android系统会报错误。在进行绑定时会涉及到一个ServiceConnection类,当绑定成功时会回调其中的onServiceConnected()方法。

        在进行绑定服务的时候相关的生命周期方法是:onCreate()、onBind()、onUnbind()、onDestory();

bindService()绑定服务:

unBindService()解除绑定:

多次调用bindService()绑定服务时,不会重复调用生命周期函,一下是3次绑定1次解除绑定的log:

三、同时使用两种方式来启动Service服务

        当我们同时使用了startService()开始服务和bindService()绑定服务时,必须调用一次stopService()和unBindService()才能够销毁一个服务。大家跟着我的操作来一起看看log日志:


操作步骤:

1、startService()开始服务

2、bindService()绑定服务

3、startService()开始服务

4、bindService()绑定服务

5、stopService()服务

6、startService()开始服务

7、startService()开始服务

8、stopService()服务

9、unBindService()服务

源代码部分:

Activity代码:

public class SjcServiceActivity extends Activity {
	
	Intent startServiceIntent;
	ServiceConnection connection;
	boolean isBindService = false;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_service);
		
		startServiceIntent = new Intent(this, MyStartService.class);
		connection = new ServiceConnection() {
			
			//当绑定的服务崩溃或被杀死导致的连接中断时被调用,自己解除绑定时则不会被调用
			public void onServiceDisconnected(ComponentName name) {
				Log.i("TAG", "MyStartService --> onServiceDisconnected");
				unBindServie();
			}
			
			//当绑定服务时会调用这个方法
			public void onServiceConnected(ComponentName name, IBinder service) {
				isBindService = true;
				Log.i("TAG", "MyStartService --> onServiceConnected");
			}
		};
	}
	
	protected void onDestroy() {
		super.onDestroy();
		unBindServie();//当Activity销毁时,必须解除所绑定的服务,不然会报错
	}
	
	
	public void onClick(View v) {
		
		Button btn = (Button)v;
		
		switch (v.getId()) {
		case R.id.btn_startService:
			startService(startServiceIntent);
			break;
			
		case R.id.btn_stopService:
			stopService(startServiceIntent);
			break;
			
		case R.id.btn_bindService:
			bindService(startServiceIntent, connection, Context.BIND_AUTO_CREATE);
			break;
			
		case R.id.btn_unbindService:
			unBindServie();
			break;

		default:
			Toast.makeText(this, btn.getText(), Toast.LENGTH_SHORT).show();
			break;
		}
	}
	
	private void unBindServie() {
		if(isBindService) {
			isBindService = false;
			unbindService(connection);
		} 
	}
}

Activity的布局xml文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center"
        >
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start Service"
            android:id="@+id/btn_startService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Stop Service"
            android:id="@+id/btn_stopService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Bind Service"
            android:id="@+id/btn_bindService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Unbind Service"
            android:id="@+id/btn_unbindService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        
    </LinearLayout>
    

</FrameLayout>

Service代码:

public class MyStartService extends Service {
	
	public void onCreate() {
		super.onCreate();
		Log.i("TAG", "MyStartService --> onCreate");
	}
	
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		Log.i("TAG", "MyStartService --> onStart");
	}
	
	//在Android2.0时系统引进了onStartCommand方法取代onStart方法,
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("TAG", "MyStartService --> onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	//服务在绑定时调用,
	//如果返回值为null,则不会调用ServiceConnection的onServiceConnected()方法
	public IBinder onBind(Intent intent) {
		Log.i("TAG", "MyStartService --> onBind");
		return new Binder() {
			
		};  
	}
	
	public boolean onUnbind(Intent intent) {
		Log.i("TAG", "MyStartService --> onUnbind");
		return super.onUnbind(intent);
	}
	
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this, "service destroy", Toast.LENGTH_SHORT).show();
		Log.i("TAG", "MyStartService --> onDestroy");
	}

}

Service在清单文件中的注册:

<service android:name="com.sjc.myproject.apis.service.MyStartService"></service>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章