• Android四大组件之—— 使用服务进行后台操作


    什么是服务

           服务是一个没有可视化界面的组件,它可以在后台长期运行并进行各种操作。

    服务的创建

           我们只需要继承Service类并实现相应的方法即可创建服务

           要想启动服务,还得在AndroidManifest中注册服务

    服务类的示例代码

    package com.whathecode.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.widget.Toast;
    
    public class ExtendsionService extends Service
    {
    
    	/**
    	 * 当服务第一次被创建的时候调用此方法
    	 */
    	@Override
    	public void onCreate()
    	{
    		
    		super.onCreate();
    		Toast.makeText(getBaseContext(), "服务被创建了", Toast.LENGTH_SHORT).show();
    	}
    	
    	/**
    	 * 当通过startService方法启动服务时此方法被调用
    	 */
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId)
    	{
    		Toast.makeText(getBaseContext(), "服务被启动了", Toast.LENGTH_SHORT).show();
    		return super.onStartCommand(intent, flags, startId);
    	}
    
    	@Override
    	public IBinder onBind(Intent intent)
    	{
    		return null;
    	}
    
    	@Override
    	public void onDestroy()
    	{
    		super.onDestroy();
    	}
    
    }
    

     

    使用startService启动服务

    主界面的逻辑代码:

    package com.whathecode.servicedemo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    
    public class MainActivity extends Activity
    {
    
    	Intent service = null;
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		//创建服务
    		service = new Intent(this, ExtendsionService.class);
    	}
    
    	public void start(View view)
    	{
    		//启动服务
    		startService(service);
    	}
    	
    	public void stop(View view)
    	{
    		//停止服务
    		stopService(service);
    	}
    }
    

    注册服务:

     

    <service android:name="com.whathecode.servicedemo.BackgroundService"></service>

     

    运行效果:

     

    startService

    注意:

             当我们第一次点击启动服务按钮的时候,onCreate方法和onStartCommand方法依次执行,

             但在第二次点击启动服务按钮的时候,这个服务已经处于运行状态,onCreate方法不再执行第二次,

             而onStartCommand方法总是在调用startService启动服务的时候执行。

             onDestroy方法在stopService方法被调用后执行。

    除了使用startService方法启动服务外,我们还可以使用Bind的方式启动服务。

    前者和后者的不同在于:

          服务的生命周期不依赖于启动者。服务被启动后一直在后台运行直到调用stopService被停止。

           使用Bind方式启动服务,服务的生命周期依赖于启动者。即服务在启动者退出后自动销毁。

    使用Bind方式启动服务

    主要使用bindService方法启动服务,unbindService方法销毁服务。

    使用此方式启动服务的好处是,bind定成功的时候服务返回一个IBinder对象,

    我们可以通过在服务类里面实现这个对象,从而访问服务里面的具体方法。

    从而达到和服务沟通的目的。

    注意:

            我们不能以直接实例化服务的方式调用里面的方法。

     

    另外:

           如果在退出服务的时候没有解绑,那么程序就会抛出异常IllegalArgumentException异常。

           因此,每次调用bindService启动服务,完成后需要退出服务都需要使用unbindService 解绑。  

    示例代码:

    package com.whathecode.servicedemo;
    
    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;
    
    public class MainActivity extends Activity
    {
    
    	Intent service = null;
    	IReceptionist rpst;
    
    	/**
    	 * bindService和unbindService方法使用的参数
    	 */
    	private ServiceConnection conn = new ServiceConnection()
    	{
    		
    		//此方法在服务连接被意外终止的时候被调用,
    		@Override
    		public void onServiceDisconnected(ComponentName name)
    		{
    		
    		}
    		
    		//当服务被连接上的时候自动调用这个方法,第二个参数是服务类onBind方法中返回的对象
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service)
    		{
    			rpst = (IReceptionist) service;
    			rpst.callExtendsionNumber();
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		//创建服务
    		service = new Intent(this, ExtendsionService.class);
    	}
    
    	public void start(View view)
    	{
    		//启动服务
    		startService(service);
    	}
    	
    	public void stop(View view)
    	{
    		//停止服务
    		stopService(service);
    	}
    	
    	public void bind(View view)
    	{
    		//绑定服务
    		bindService(service, conn , BIND_AUTO_CREATE);
    	}
    	
    	public void unBind(View view)
    	{
    		//解绑服务
    		unbindService(conn);
    	}
    }
    

     

    继承ServiceBinder对象,并实现自定义接口:

    通过这个方式,我们可以暴露只需要的方法,实现代码的保护。

     

    IReceptionist接口代码:
    package com.whathecode.servicedemo;
    
    public interface IReceptionist 
    {
    	public void callExtendsionNumber();
    }
    

    ExtendsionService服务类代码:

     

    package com.whathecode.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.Toast;
    
    public class ExtendsionService extends Service
    {
    
    	private static final String TAG = "ExtendsionService";
    
    	/**
    	 * 当服务第一次被创建的时候调用此方法
    	 */
    	@Override
    	public void onCreate()
    	{
    		
    		super.onCreate();
    		Toast.makeText(getBaseContext(), "服务被创建了", Toast.LENGTH_SHORT).show();
    	}
    	
    	/**
    	 * 当通过startService方法启动服务时此方法被调用
    	 */
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId)
    	{
    		Toast.makeText(getBaseContext(), "服务被启动了", Toast.LENGTH_SHORT).show();
    		return super.onStartCommand(intent, flags, startId);
    	}
    
    	@Override
    	public IBinder onBind(Intent intent)
    	{
    		return new ServiceBinder();
    	}
    
    	@Override
    	public void onDestroy()
    	{
    		Toast.makeText(getBaseContext(), "服务被销毁了", Toast.LENGTH_SHORT).show();
    		Log.d(TAG, "服务被销毁了");
    		super.onDestroy();
    	}
    	
    	public void putExtendsion()
    	{
    		Toast.makeText(getBaseContext(), "正在帮你转接分机", Toast.LENGTH_SHORT).show();
    	}
    	
    	/**
    	 * 
    	 * 继承Binder并实现IReceptionist接口
    	 * 继承Binder类的目的是onBind方法中需要返回这个类型的对象
    	 * 
    	 * 实现IReceptionist接口是暴露方法的需要
    	 */
    	private class ServiceBinder extends Binder implements IReceptionist
    	{
    		public void callExtendsionNumber()
    		{
    			putExtendsion();
    		}
    		
    		private void otherMethod()
    		{
    			
    		}
    	}
    }
    

     

    运行效果:

    bindService

    注意看上图,我们在按下返回键的时候,Activity被销毁,由它启动的服务也跟着被销毁。

    这样的服务貌似作用不大,有没有办法在退出Activity的时候不退出服务呢?

    答案是有的:Android允许我们先启动一个服务,然后再调用bindService绑定到服务,

                        这样,我们既可以达到和服务沟通的目的,也可以使服务长期在后台运行。

     

    看下图:

    bindService

    通过下面的图,就可以更清楚地理解上面代码的工作原理:

    Service

  • 相关阅读:
    踏个脚印,今天在博客园安了个家!
    微软WebDeployment Project插件发布网站时老是报出"aspnet_merge.exe”已退出,代码为1的错误
    从xap文件中读取文件
    ASP.NET MVC学习笔记二(URL映射规则)
    Siverlight Contrib的alpha版与正式版有很大区别
    带你尝鲜LiteOS 组件EasyFlash
    带你了解几种二进制代码相似度比较技术
    让数据大白于天下:GCC插件实现代码分析和安全审计
    鸿蒙轻内核源码分析:MMU协处理器
    高性能云网关,打通云内外业务互通的任督二脉
  • 原文地址:https://www.cnblogs.com/ai-developers/p/4271939.html
Copyright © 2020-2023  润新知