android Service

Service组件

服务没有可视化接口,可以在后台运行。
生命周期:onCreate() ------->onStart(Intent intent , int startId)----------->onDestroy()
服务必须显示调用才可启动。
开机启动一个服务:
需要借助BroadCast监听开机事件,然后在onReceive()中启动服务。


启动服务的2中方法:context.startService()  和context.bindService()

1、context.startService()

此种方式启动service时会一次调用

context.startService() --------> onCreate()----->onStart()(service可被启动多次,如果service正在运行,则直接调用此方法)------>service running

context.stopService() --------> onDestroy() 

2、context.bindService()

此种方式启动service时会一次调用

context.startService() --------> onCreate()----->onBind()(只可绑定一次)------>service running

context.stopService() --------> onUnbind()----->onDestroy() 

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的运行状态等。

此时调用者和Service绑定在一起,Context退出了,service就会调用相应的onUnbind()方法。


AIDL(Android Interface  Definition Language)实现跨进程访问

AIDL(android接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务类。Service的实现类需要去继承这个stub服务类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:

service端进程:

首先建立一个android项目,并建立一个简单的AIDL服务(可看做一个接口),如下:

在包下建立一个aidl文件IService.aidl:

package com.service;

interface IService{
String getValue();
}

写一个Service类,在类中定义一个内部类MyServiceImpl ,该类实现aidl文件对应的stub服务类,如下:

public class MyService extends Service{
	
	private String text="";
	@Override
	public IBinder onBind(Intent intent) {
		return new MyServiceImpl();//此处必须返回一个 IService的实现类
	}
	
	public class MyServiceImpl extends IService.Stub{


		@Override
		public String getValue() throws RemoteException {
			text = text +"io";
			return text;
		}
	}
	
}


在manifest文件中配置此service,如下:



//此处是客户端用来访问AIDL服务的ID


调用服务的进程:

建立一个android项目作为客户端。

第一步:将service端项目生成的gen文件夹下的类(包括包)复制到调用服务的进程的src目录下。

第二步:写一个activity调用此服务:

package com.client;

import com.service.IService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class IClient extends Activity implements OnClickListener{
	
	private IService iService =null;
	private Button bind,invoke;
	private TextView text;
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			iService = IService.Stub.asInterface(service);
			invoke.setEnabled(true);
		}
	};
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bind = (Button)findViewById(R.id.bind);
        invoke = (Button)findViewById(R.id.invoke);
        invoke.setEnabled(false);
        bind.setOnClickListener(this);
        invoke.setOnClickListener(this);
        text = (TextView)findViewById(R.id.text);
    }
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		case R.id.bind:
			bindService(new Intent("com.service.serviceio"), serviceConnection, Context.BIND_AUTO_CREATE);
			break;
		case R.id.invoke:
			try {
				text.setText(iService.getValue());
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
	}
}


此时就可实现访问service端的数据。

注意:AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据就需要进一步的处理。

AIDL服务支持的数据类型有:

java的简单类型:int char boolean 等

String 和CharSequence

List和Map;对象元素的类型也必须是AIDL服务支持的类型

AIDL自动生成的接口(需要import)

实现android.os.Parcelable接口的类(需要import)



研究中...

你可能感兴趣的:(android Service)