android基础之Service

                                                                             android基础之Service

一:Service的概述

   Service是Android四大基本组件(Service,Activity,Context Provider,BroadcastReceiver它们之间依靠Intent建立联系)中与Activity最相似的组件。都代表 执 行的程序,Service与Activity的区别在于:

   Service一直在后台运行,它没有用户界面,所以绝不会到前台 来。一旦Service被启动起来之后,它就与Activity一样。完全具有自己的生命周期。

   关于程序中Activity和service的选择标准:

   如果某个程序组件需要在运行时向用户呈现某种界面,或者该程序需要与用户交互,就需要使用Activity,否则就应该考虑使用Service了。

   如:下载东西,播放音乐。可以一边下载,一边播放,一边玩其他的事情。但是Activity是无法做到的。只要Activity被关闭或者最小化了,程序就停止了。

二:特点

1.没有UI

2.进行耗时较长或者与用户没有交互的一些功能

3.Service具有较高的优先级,比stop的Activity优先级要高,最高的优先级是前台Activity

4.具有较长的生命周期




三.使用


看到这里你也许会问为什么Service会有2中生命周期呢。哈哈,

其实这是跟Service的使用方式有关的。Service有2中不同的使用方式。

我们先创建一个android application project工程,然后在默认包下新建一个class,取名为firstService 继承Service如图:


既然Service是我们自定义的,当然我们要在清单文件里面注册一下。(在AndroidManifest.xml的 <application>标签加入如下内容):


name里面放的是类的包名+类名,一般会有提示。

第一种使用方式(对应最左边的图)



这里我在主界面放了个按钮,然后设置的android:onClick="btn2"

这种方式启动的Service,并没有将之与Activity绑定,所以作为一个单独存在的实体,本身的生命周期不受别人影响。也没有办法与其他组件之间进行数据交互。

就像我们电脑的一些一些系统服务一样,很多时候我们是通过强制手段关闭的。


第二种方式,对应最右边的图。

通常情况下,我们希望一个后台的Service是可控的,同时用户也希望知道这个服务的运行状态,就拿下载东西来说,有的时候用户希望看到实时的数据变化。第一种方式在这种情况下显然不能满足我们的需求,毕竟大多数场景下,用户希望服务受自己掌控,同时灵活的数据是app的灵魂。

我们知道,service没有ui所以要通过Activity提供ui。第二种方式就是通过activity与service的绑定实现的。用同样的方式,我们在布局里面再放一个按钮,然后设置的android:onClick="btn1"在activity的主函数里面定义按钮点击事件。


前面都差不多。就启动时用

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

启动。原理都说的差不多了。建议写代码时对着生命周期来写。

package com.example.mydemo;

import com.example.mydemo.secondService.mybinder;

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.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

	private mybinder mybinder;
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		//当访问者与之连接成功时调用
		@Override
		public void onServiceConnected(ComponentName name, IBinder ibinder) {
			// TODO Auto-generated method stub
			mybinder = (com.example.mydemo.secondService.mybinder) ibinder;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	/**
	 * startService所启动的服务
	 * 1.它是不受任何人影响的
	 * 2.它是作为一个单独的个体存在的,没有办法与其他组件之间进行数据交互
	 * @param view
	 */
	public void btn(View view){
		Toast.makeText(MainActivity.this, mybinder.getCount()+"", Toast.LENGTH_LONG).show();
	}
	
	public void btn1(View view){
		unbindService(serviceConnection);
	}
	
	public void btn2(View view){
		Intent intent = new Intent(this,secondService.class);
	//	startService(intent);
		bindService(intent, serviceConnection, BIND_AUTO_CREATE);
	}

	/**
	 * 如果使用bindServiuce启动的服务,那么service就与调用者的生命周期就有关联了,
	 * 所以退出时也要终止service
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unbindService(serviceConnection);
		super.onDestroy();
	}
	
	
	
}

创建2个service自己随便取名字,别忘了在清单文件注册就是。


第一个service对应第一种启动方式:

package com.example.mydemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class firstService extends Service {

	
	final String tag = "firstService";
	boolean flag = true;//逻辑控制开关
	int count=0;//测试参数
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onCreate()");
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onStartCommand()");
		new Thread(){
			public void run() {
				while(flag){
					System.out.println("进度:"+count++);
					if(count>99){
						flag=false;
					}
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				
			}		
		}.start();;
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onDestroy()");
		flag = false;
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

}
第一个service对应第二种启动方式:

package com.example.mydemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;


public class secondService extends Service{

	boolean flag = true;	
	final String tag = "secondService";
	int count=0;
	class mybinder extends Binder{
		public int getCount(){
			return count;
		}
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onCreate()");
		super.onCreate();
	}


	//建立契约
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onBind()");
		new Thread(){
			public void run() {
				while(flag){
					System.out.println("进度:"+count++);
					if(count>100){
						flag=false;
					}
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				
			}		
		}.start();
		return new mybinder();
	}

	//解除契约
	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onUnbind()");
		return super.onUnbind(intent);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		flag = false;
		Log.i(tag, tag+"....onDestroy()");
		super.onDestroy();
	}

}
activity的主函数调用

package com.example.mydemo;

import com.example.mydemo.secondService.mybinder;

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.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

	private mybinder mybinder;
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		//当访问者与之连接成功时调用
		@Override
		public void onServiceConnected(ComponentName name, IBinder ibinder) {
			// TODO Auto-generated method stub
			mybinder = (com.example.mydemo.secondService.mybinder) ibinder;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	/**
	 * startService所启动的服务
	 * 1.它是不受任何人影响的
	 * 2.它是作为一个单独的个体存在的,没有办法与其他组件之间进行数据交互
	 * @param view
	 */
	public void btn(View view){
		Toast.makeText(MainActivity.this, mybinder.getCount()+"", Toast.LENGTH_LONG).show();
	}
	
	public void btn1(View view){
		unbindService(serviceConnection);
	}
	
	public void btn2(View view){
		Intent intent = new Intent(this,secondService.class);
	//	startService(intent);
		bindService(intent, serviceConnection, BIND_AUTO_CREATE);
	}

	/**
	 * 如果使用bindServiuce启动的服务,那么service就与调用者的生命周期就有关联了,
	 * 所以退出时也要终止service
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unbindService(serviceConnection);
		super.onDestroy();
	}
	
	
	
}
效果就不发了。反正第二种方式所打开的service它的生命周期已经和activity绑定了。
这种方式可以让我们自定义地暂停和重启服务。








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