Android学习之Service(二)

来源:互联网 发布:西古德森实况数据 编辑:程序博客网 时间:2024/05/18 00:26

刚看了本地服务的相关知识,又迫不及待的看了远程服务。虽说远程服务比较复杂,但是慢慢看,并不断的敲代码,最后能够跑起来还是很开心的。虽然只是简单的小程序,但是主要还是了解其中的机制,不是吗?大笑
远程服务,我们有叫他AIDL(Android Interface Definition Language)服务吧,据说可是最复杂的服务类型呢。不要怕,慢慢简化他。
在Android中我们需要使用IDL(Interface Definition Language)来定义将向客户端公开的接口,这里IDL就是称为AIDL。
下面开始操作。
首先我们先创建服务器端:
1.新建一个android项目,我这里叫“BrainsService”;
2.新建你自己的包(这个包用来存放AIDL文件,扩展名为.aidl),根据我操作的结果,报名最后是已.aidl结束,比如我的包就是:”com.hdf.service.aidl“;
在这个包里新建一个后缀为.aidl的文件,并在这个文件写入如下内容:

package com.hdf.service.aidl;interface IMyServiceAIDL{double getValue(String value);}
这段内容的写法同JAVA相似,但不是java语句哦,不能加修饰符(public ....)。里面的double getValue(String value),根据自己要求自己定义就好,我这里就是接受一个String型返回一个双精度数字。注意啦:这个文件只要你成功创建后会在项目的gen目录下自动生成一个适合RPC通信的接口。这里就不展示这哥生成的文件了,太长。
3.下面,我们需要新建一个类来扩展android.app.Service并实现刚才新建的IMyServiceAIDL接口。我这里新建立一个类为IMyService,代码如下:
package com.hdf.service.aidl;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class IMyService extends Service {private static final String TAG = "IMyService";public class IMyServiceImpl extends IMyServiceAIDL.Stub{//IMyServiceAIDL.Stub充当着远程服务的实现,这里的Stub也是自动生成的一个抽象类public double getQuote(String value) throws RemoteException {Log.v(TAG, "getQuote() called for " + value);return 20.0;}} //实现onBind方法,区别于本地服务@Overridepublic IBinder onBind(Intent intent) {Log.v(TAG,"onBind called....");return new IMyServiceImpl();//返回IMyServiceImpl对象,否则客户端无法获得服务对象}@Overridepublic void onCreate() {super.onCreate();Log.v(TAG,"onCreate called....");}@Overridepublic void onDestroy() {super.onDestroy();Log.v(TAG,"onDestory called....");}@Overridepublic void onStart(Intent intent, int startId) {super.onStart(intent, startId);Log.v(TAG,"onStart called....");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubreturn super.onStartCommand(intent, flags, startId);}}
4.最后需要在AndroidManifest.xml注册服务信息:
<service android:name="com.hdf.service.aidl.IMyService"><intent-filter><action  android:name="com.hdf.service.aidl.IMyServiceAIDL"/></intent-filter></service>
到这里服务器端算是大功告成啦。
下面我们开始创建客户端,当然要另外新建一个新的安卓项目了。OK。
1.新建新项目,我在这里命名为”Brains"
2.将上一个项目建的aidl文件拷贝过来就好了,最好连包一起拷贝过来,因为aidl文件对包很敏感的。
3.新建一个activity类,代码如下:
package com.hdf.AIDLService;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.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.hdf.service.aidl.IMyServiceAIDL;public class BrainsActivity extends Activity implements OnClickListener {    /** Called when the activity is first created. */private Button b1,b2,b3;private IMyServiceAIDL service = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                b1 = (Button)findViewById(R.id.button1);        b2 = (Button)findViewById(R.id.button2);        b3 = (Button)findViewById(R.id.button3);        b1.setOnClickListener(this);        b2.setOnClickListener(this);        b3.setOnClickListener(this);    }@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint id = v.getId();switch(id){case R.id.button1://调用bindService方法,建立服务连接bindService(new Intent(IMyServiceAIDL.class.getName()), conn, Context.BIND_AUTO_CREATE);b1.setEnabled(false);b2.setEnabled(true);b3.setEnabled(true);break;case R.id.button2:callService();break;case R.id.button3://调用unbindService方法,销毁服务连接unbindService(conn);b1.setEnabled(true);b2.setEnabled(false);b3.setEnabled(false);break;}}public void callService(){double val;try {val = service.getValue("SYH");Toast.makeText(this, "value from service is "+ val, Toast.LENGTH_LONG).show();} catch (RemoteException e) {Log.e("BrainsActivity",e.getMessage(),e);}}private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {Log.v("BrainsActivity", "onServiceDisconnected() called....");service = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder s) {Log.v("BrainsActivity","onServiceConnected() called....");service = IMyServiceAIDL.Stub.asInterface(s);//callService();}};}
4.布置XML布局文件,如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent"><TextView android:layout_width="fill_parent"android:layout_height="wrap_content" android:text="@string/hello" /><Button android:text="Bind" android:id="@+id/button1"android:layout_width="fill_parent" android:layout_height="wrap_content"></Button><Button android:text="Call Again" android:id="@+id/button2"android:layout_width="fill_parent" android:layout_height="wrap_content"></Button><Button android:text="UnBind" android:id="@+id/button3"android:layout_width="fill_parent" android:layout_height="wrap_content"></Button></LinearLayout>
OK。客户端也写好了。

将服务端和客户端都运行,之后你就能看到效果啦...
你看了会说不复杂吗,哈哈,那说明你还是很牛的啦。我就的慢慢琢磨了。关于AIDL很有更复杂的就是向服务传递和接受复杂的类型。嗯,继续学习...........

最后我贴出我的两个项目的文件夹结构图吧:




原创粉丝点击