zoukankan      html  css  js  c++  java
  • 关于Android中的四大组件(Service的开启与关闭)

    前言


    服务(Service)是Android系统中的四大组件之中的一个。服务主要用于两个目的:后台执行和跨进程訪问。

    通过启动


    一个服务。能够在不显示界面的前提下在后台执行指定的任务,这样能够不影响用户做其它事情。通过AIDL服务能够


    实现不同进程之间的通信,这也是服务的重要用途之中的一个。


    Service基础


    Service并没有实际界面,而是一直在Android系统的后台执行。一般使用Service为应用程序提供一些服务。或不


    须要界面的功能,比例如以下载文件、播放音频等


    怎样创建与配置Service


    在日常开发中Service的创建与配置能够依照下面两个步骤进行:


    (1)定义一个继承Service的子类。


    (2)在AndroidManifest.xml文件里配置该Service。


    Service与Activity一样,也有一个启动到销毁的过程。只是这个过程Service要比Activity简单多了。

    一个服务实际


    上是一个继承自android.app.Service的类。查看Service源代码。能够看出Service实际上是一个抽象类,在这个抽象类


    中有一个抽象方法onBind,因此我们在继承一个Service类时。必需要实现这种方法。


    public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
    	.......
    	public abstract IBinder onBind(Intent intent);
    	.......
    }


    以下类定义了一个Service组件。


    public class MyFirstService extends Service{
    
    	public static final String TAG="MyFirstService";
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		return null;
    	}
    	
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		Log.e(TAG, "--------onCreate--------");
    	}
    	
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		Log.e(TAG, "--------onStartCommand--------");
    		return super.onStartCommand(intent, flags, startId);
    	}
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		Log.e(TAG, "--------onDestroy--------");
    	}
    
    }


    以上代码完毕了创建Service。接下来须要在AndroidMainfest.xml文件里进行配置该Service,下面配置代码展示了


    怎样配置Service:


    <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".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.servicetest.startservice.MyFirstService" >
            </service>
        </application>


    到了这一步我们的Service组件已经创建完成。接着我们能够启动Service了,在Android系统中启动Service有两种


    方式,各自是startService和bindService。

    startService使用


    以下程序通过两个button进行启动与停止Service,演示Service通过startService从创建到销毁整个过程。

    public class MyFirstService extends Service{
    
    	public static final String TAG="MyFirstService";
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		return null;
    	}
    	
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		Log.e(TAG, "--------onCreate--------");
    	}
    	
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		Log.e(TAG, "--------onStartCommand--------");
    		return super.onStartCommand(intent, flags, startId);
    	}
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		Log.e(TAG, "--------onDestroy--------");
    	}
    
    }


    两个button的点击事件:


    @Override
    public void onClick(View v) {
    	switch (v.getId()) {
    	case R.id.btn_startService:// startService
    		startService(serviceIntent);
    		break;
    	case R.id.btn_stoptService:// stopService
    		stopService(serviceIntent);
    		break;
    	default:
    		break;
          }
    }




    以上是我们创建的Service组件,接下来对Service进行操作。


    (1)当单击一次启动(startService)button时:






    (2)当服务被启动后单击一次停止(stopService)button时:



    从上面能够看出Service从创建到销毁分别经历了 onCreate---->onStartCommand---->onDestroy


    (3)当我们反复开启Service时:






    从上图能够看出。每当Service被创建时回调onCreate方法。每次Service被启动时都会回调onStartCommand方


    法。多次启动一个已有的Service组件将不会再回调onCreate方法,但每次启动时都会回调onStartCommand方法。


    当中,当我按下home键时。并没有回调onDestroy方法,也就是说此Service并没有随着Android系统的关闭而关


    闭。




    bindService的使用


    使用startService方法启动服务。当程序被强制退出时。而且没有调用stopService来停止服务,Service会保持在


    后台一直执行。直到Android系统关闭或调用stopService方法后才会停止。

    假设我们希望在启动服务的Activity关闭后


    服务自己主动关闭,这就须要将Activity和Service进行绑定。



    通过bindService方法能够将Activity和Service绑定。bindService方法的定义例如以下:


    public boolean bindService(Intent service, ServiceConnection conn,int flags) 


    该方法的三个參数含义例如以下:


    (1)service:该參数通过Intent指定要启动的Service。


    (2)conn:该參数的类型是ServiceConnection。负责连接Intent对象指定的服务。

    当訪问者与Service之间连接


    成功时将回调ServiceConnecttion对象的onServiceConnected(ComponentName name,IBinder service)方法。当


    Service所在的宿主进程因为异常终止或因为其它原因终止,导致该Service与訪问者之间断开连接时回调


    ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。


    (3)flags:该參数是一个标志位。一般设为Context.BIND_AUTO_CREATE。


    下面创建了一个继承Service的类。在该类中添加了几个与绑定相关的事件方法:


    public class MyFirstService extends Service{
    	
    	private String info;
    	private MyBinder myBinder=new MyBinder();
    
    	public static final String TAG="MyFirstService";
    
    	/**
    	 * 又一次绑定时调用该方法
    	 */
    	@Override
    	public void onRebind(Intent intent) {
    		super.onRebind(intent);
    	}
    	
    	/**
    	 * 解除绑定时调用该方法
    	 */
    	@Override
    	public boolean onUnbind(Intent intent) {
    		return super.onUnbind(intent);
    	}
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		return myBinder;
    	}
    	
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		Log.e(TAG, "--------onCreate--------");
    		info="onCreate";
    	}
    	
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		Log.e(TAG, "--------onStartCommand--------");
    		return super.onStartCommand(intent, flags, startId);
    	}
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		Log.e(TAG, "--------onDestroy--------");
    	}
    	
    	public class MyBinder extends Binder{
    		public String getInfo(){
    			return info;
    		}
    	}
    
    }


    public class MainActivity extends Activity implements OnClickListener {
    
    	private Button btn_startService;
    	private Button btn_stopService;
    	private Button btn_bindService;
    	private Button btn_unbindService;
    	private Button btn_getinfo;
    
    	private Intent serviceIntent;
    
    	private MyFirstService.MyBinder myBinder;
    
    	private ServiceConnection conn = new ServiceConnection() {
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			Log.e(MyFirstService.TAG, "------onServiceDisconnected---------");
    		}
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			Log.e(MyFirstService.TAG, "------onServiceConnected---------");
    			myBinder = (MyFirstService.MyBinder) service;
    		}
    	};
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		initData();
    		initView();
    		initEvent();
    	}
    
    	private void initData() {
    		serviceIntent = new Intent(this, MyFirstService.class);
    	}
    
    	private void initView() {
    		btn_startService = (Button) this.findViewById(R.id.btn_startService);
    		btn_stopService = (Button) this.findViewById(R.id.btn_stoptService);
    		btn_bindService = (Button) this.findViewById(R.id.btn_bindService);
    		btn_unbindService = (Button) this.findViewById(R.id.btn_unbindService);
    		btn_getinfo = (Button) this.findViewById(R.id.btn_getinfo);
    	}
    
    	private void initEvent() {
    		btn_startService.setOnClickListener(this);
    		btn_stopService.setOnClickListener(this);
    		btn_bindService.setOnClickListener(this);
    		btn_unbindService.setOnClickListener(this);
    		btn_getinfo.setOnClickListener(this);
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.btn_startService:// startService
    			startService(serviceIntent);
    			break;
    		case R.id.btn_stoptService:// stopService
    			stopService(serviceIntent);
    			break;
    		case R.id.btn_bindService:// bindService
    			bindService(serviceIntent, conn, Service.BIND_AUTO_CREATE);
    			break;
    		case R.id.btn_unbindService:// unbindService
    			unbindService(conn);
    			break;
    		case R.id.btn_getinfo:// 获取数据
    			Toast.makeText(MainActivity.this, myBinder.getInfo(),
    					Toast.LENGTH_SHORT).show();
    			break;
    		default:
    			break;
    		}
    	}
    
    }



    执行效果:





    在MyFirstService类中定义了一个MyBinder类。该类用于获取一个String类型的返回值,


    ServiceConnection.onServiceConnected方法的第2个參数是一个IBinder类型的变量,将该參数转换成


    MyFirstService.MyBinder对象,并使用myBinder.getInfo()方法获取String类型的值。


    接着看下我们是怎样使用bindService和unbindService操作的。


    (1)当我们单击一次bindService(bindService(service,conn,flags))button时:







    (2)当我们单击一次unbindServicebutton时:




    从上面能够看出通过bindService开启服务。再通过unbindService停止服务的过程是 onCreate------>onBind------


    ->onServiceConnected------->onUnbind------>onDestory


    这里面值得注意的是。当我按下home键时。此时并没有调用unbindService方法进行停止服务。但依旧能打印出


    onUnbind---->onDestory,也就是说通过bindService开启的服务是随着Activity的销毁而销毁。


    Service的生命周期


    下图的左半部分是通过startService()方法启动时的Service生命周期,右半部分是通过bindService()方法启动时


    的Service生命周期。








    Service生命周期有一种特殊的情形,假设Service已由某个client通过startService()方法启动了,接下来其它客


    户端再调用bindService()方法来绑定该Service后。再调用unbindService()方法解除绑定,最后又调用了bindService()


    方法再次绑定到Service,这个过程所触发的生命周期例如以下:





    进行拆解步骤:


    (1)调用startService时的生命周期:onCreate------>onStartCommand


    (2)调用bindService时的生命周期:onBind------>onServiceConnected


    (3)调用unbindService时的生命周期:onUnbind


    (4)再一次调用bindService时的生命周期:onServiceConnected----->onRebind



    以上调用unbindService时。并没有回调onDestroy()方法,这是由于该Service并非由Activity通过bindService()


    方法来启动的,因此当Activity调用unbindService()方法取消与该Activity的绑定时,该Service也不会终止。当Activity


    调用bindService()绑定一个已经启动的Service时,系统仅仅是把Service内部IBinder对象传给Activity,当Activity调用


    unbindService()方法取消与该Service的绑定时,仅仅是切断了Activity与Service之间的联系。并不能停止Service组件。





    -------------------------------------------------------------------------------------------------------------------------------------------------------

    转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/47722185情绪控





  • 相关阅读:
    django 之 用户忘记密码的解决办法
    Django 富文本ckeditor 在模板中的实现
    MySQL密码的恢复方法
    sublime 快捷键
    linux 修改用户密码
    ubuntu 下重启 mysql
    python 控制浏览器模块
    读书笔记:从小工到专家(一)
    urlparse 模块
    python 标准内建函数
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6865906.html
Copyright © 2011-2022 走看看