Android Service随笔
一,Service概述。
Service在android语言中,是运行在后台的,没有界面,但是它依然运行在主线程中,不可做耗时的操作,如下载,更新界面等等。我们使用Service有两种方法,三种模式。
首先,service(服务)有两种:
1:本地服务, Local Service 用于应用程序内部。在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。
提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。
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);
}
}下面是启用的servicepublic 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文件。服务端
客户端
本文详细介绍了Android中Service的两种类型及其工作原理,包括本地服务和远程服务的启动与停止过程。同时,阐述了回调函数的概念及其在Android中的应用,通过具体的代码示例展示了如何实现服务间的通信及调用方法。
4753

被折叠的 条评论
为什么被折叠?



