Android Service随笔

本文详细介绍了Android中Service的两种类型及其工作原理,包括本地服务和远程服务的启动与停止过程。同时,阐述了回调函数的概念及其在Android中的应用,通过具体的代码示例展示了如何实现服务间的通信及调用方法。

Android Service随笔

一,Service概述。

Service在android语言中,是运行在后台的,没有界面,但是它依然运行在主线程中,不可做耗时的操作,如下载,更新界面等等。我们使用Service有两种方法,三种模式。

首先,service(服务)有两种:

1:本地服务, Local Service 用于应用程序内部。在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止

2:远程服务, Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。

提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。

context.startService() ->onCreate()- >onStart()->Service running--调用context.stopService() ->onDestroy()

context.bindService()->onCreate()->onBind()->Service running--调用>onUnbind() ->onDestroy() 

二,先来复习下回调函数。

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

最简单的回调如button的onclick方法,假设class A中设置button.setOnclickListener(new OnClickListener);这样就把一个实现了OnClickListener的对象传给了Button类。当执行了button.click();事件后,在button内部就使用传过来的OnClickListener对象,使用OnClickListener的方法,这样做到了回调的概念。

	//定义的接口,当将实现了此接口的对象传给了button,只要在button中用此接口接受各种传入的类,就可一统一的使用需要的方法
	public interface OnClickListener {

	    public void OnClick(Button b);
	}
	public class Button {
		//使用接口接受传入的所有的实现了接口的类,使用多态性,可以使用子类的onclick方法。
		OnClickListener listener;
		
		public void click() {
			listener.OnClick(this);
		}
		
		public void setOnClickListener(OnClickListener listener) {
			this.listener = listener;
		}
	
	}
	public class Activity {

		  public Activity() {
		  }

		  public static void main(String[] args) {

		    Button button = new Button();
		    //将OnclickListener的实例传入Button中,这样在某种条件下,触发了Onclick的方法,实现了回调
		    button.setOnClickListener(new OnClickListener(){

		       @Override
		       public void OnClick(Button b) {
		                 System.out.println("clicked");
		       }   
		    });
		    //这个是触发方法,使button可以调用传入的OnclickListener对象
		    button.click(); //user click,System call button.click();
		  }
		}

三,bindService

如果是本地服务,要使用bindService,方法如下:

首先是Activity,开启了service,目的是调用service中的funInServer方法,由于service与activity要通信,当activity使用了bindservice使service起来之后,调用了service中的onBind方法,返回的是一个实现了自定义接口的一个IBinder类,当service被bind连接之后,activity中的类newServiceConnection的onServiceConnected方法,接收到了IBinder的对象,这时候,就可以调用这个实现了自定义接口的IBinder类的接口方法,从而调用到了service中的需要使用的方法。

activity

public class MainActivity extends Activity {

	private newServiceConnection conn = new newServiceConnection();
	private testInterface mInter  = null;
	private Button bt;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		bt = (Button)findViewById(R.id.bt);
		bt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				mInter.logcatFun();
			}
		});
		
		Intent myIntent = new Intent(this,testService.class);
		bindService(myIntent, conn, BIND_AUTO_CREATE);
		
	}

	private class newServiceConnection implements ServiceConnection{
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mInter = (testInterface)service;
		}
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			mInter = null;
		}
	}

	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}  
}
service

public class testService extends Service{

	private newBinder newBin = new newBinder() ;
	
	@Override
	public IBinder onBind(Intent intent) {
		return newBin;
	}
	
	private void funInServer(){
		Log.d("Log","funInServer");
	}
	
	
	private class newBinder extends Binder implements testInterface{

		@Override
		public void logcatFun() {
			funInServer();
		}
		
	} 
}

interface

public interface testInterface {
	public void logcatFun();
}

如果是远程服务,也就是说客户端和服务端在不同的应用,不同的进程,那么就和本地服务有所区别了,主要区别在于,要编写一个aidl文件,分别放置于server端和client端的同一路径下,这时当编译过代码,在gen文件夹下,会自动生成一个java文件,aidl就是一个远程服务的协议,那个生成的文件,就像是两端遵守的协议一般,所以,在server端,原来是继承Binder类并且实现自定义接口,而现在只要继承aidl所定义的接口的stub类,然后在客户端接受这个类的实例时,使用aidl定义类的Stub.asInterface(service);将传过来的实例造型成接口的类,其他与原先的方法一样。

服务端

先把service起起来,这里只用了startservice。

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Intent intent = new Intent("com.it.callback");
		startService(intent);
	}

}
下面是启用的service
public class clientService extends Service {

	private IBinder binder = new newBinder();
	
	@Override
	public IBinder onBind(Intent arg0) {
		return binder;
	}
	
	private void funInServer(){
		Log.d("Log","funInServer");
	} 
	
	private class newBinder extends testInterface.Stub{

		@Override
		public void logcatFun() throws RemoteException {
			funInServer();
		}
		
	}
	
}
客户端:
public class MainActivity extends Activity {

	private newServiceConnection conn = new newServiceConnection();
	private testInterface mInter  = null;
	private Button bt;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		bt = (Button)findViewById(R.id.bt);
		bt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				try {
					mInter.logcatFun();
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		Intent myIntent = new Intent("com.it.callback");
		bindService(myIntent, conn, BIND_AUTO_CREATE);
		
	}

	private class newServiceConnection implements ServiceConnection{
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mInter = testInterface.Stub.asInterface(service);
		}
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
	}

	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}  
}
在客户端和服务端同路径下都需要有个相同的aidl文件。

服务端

客户端






评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值