activity与service的交互

Activity访问service有两种方式,第一种是通过Ibinder接口实现步骤如下

Service类中

public class PlayerService extends Service {

private final IBinder binder = new MyBinder();

@Override

    public IBinder onBind(Intent intent) {

              return binder;

    }

 

    public class MyBinder extends Binder {

       public PlayerService getService() {

           return PlayerService.this;

       }

    }

}

通过MyBinder内部类得到当前service的实例

在要访问serviceactivity

 

 

/**

* PlayerService类中定义了一个MyBinder类,该类实际上是为了获得PlayerService的对象实例的。

* ServiceConnection接口的onServiceConnected方法中的第2个参数是一个IBinder类型的变量,

* 将该参数转换成PlayerService.MyBinder对象,并使用MyBinder类中的getService方法获得PlayerService对象。

     * 在获得PlayerService对象后,就可以在Activity中随意操作PlayerService了。

     */

public class PlayerActivity extends Activity{

private PlayerService serviceBinder;

ServiceConnection connection = new ServiceConnection() {

       public void onServiceDisconnected(ComponentName name) {

           serviceBinder = null;

       }

      

    public void onServiceConnected(ComponentName name, IBinder service) {

           serviceBinder = ((PlayerService.MyBinder)service).getService();

          

 

 

       }

    };

}

然后调用bindService() 建立连接。

这里的代码是跳转并绑定service

Intent i=new Intent();

              i.setClass(PlayerActivity.this, PlayerService.class);

              i.putExtra("mp3info", mp3Info);

              i.putExtra("MSG", AppConstant.PalyerMsg.PRE_MSG);

              startService(i);

              bindService(i, connection, Context.BIND_AUTO_CREATE);

 

得到serviceBinder后,就可以通过serviceBinder调用service里面的方法了。

第二种方式是通过aidl,具体实现如下

1.建立aidl文件,如果aidl文件的内容是正确的话,ADT会自动生成一个java接口文件(*.java)

2.建立服务类(Service的子类)

3.实现由aidl文件生成的java接口

4.AndroidManifest.xml文件中配置aidl服务。要注意的是<action>标签中android:name的属性值就是要引用该服务的ID,也就是Intent类的参数值.

 

1.Aidl文件内容

package net.blogjava.mobile.aidl;

interface IMyService

{

    String getValue();

}

2.编写完后会生成一个同名的java文件,这里是IMyService.java我们不需要管这个java文件

3.编写一个MyService. MyServiceService的子类,MyService类中定义了一个内嵌类(MyServiceImpl)该类是IMyService.Stub的子类.

package net.blogjava.mobile.aidl;

 

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

 

public class MyService extends Service {

 

    public class MyServiceImpl extends IMyService.Stub {

       @Override

       public String getValue() throws RemoteException {

           // TODO Auto-generated method stub

           return "Android/OPhone开发讲义";

       }

 

    }

    @Override

    public IBinder onBind(Intent intent) {

       return new MyServiceImpl();

    }

 

}

4.AndroidManifest.xml文件中配置MyService,因为这里是跨进程访问service所以是用指定action的方式.如果在同一个进程中可以不用过滤的intent-filter,只写一个

<service android:name=".MyService" >这样的就可以了,此处是跨进程所以代码写成这样:

 

<service android:name=".MyService" >

           <intent-filter>

              <action android:name="net.blogjava.mobile.aidl.IMyService" />

           </intent-filter>

       </service>

 

下面是客户端的代码

1.  将自动生成的IMyService.java文件连同包一起复制到客户端工程项目中

2.  客户端的代码如下(可以参考android 项目示例src目录下ch08_aidlclientch08_aidl)

package net.blogjava.mobile;

 

import net.blogjava.mobile.aidl.IMyService;

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.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

 

public class Main extends Activity implements OnClickListener {

    private IMyService myService = null;

    private Button btnInvokeAIDLService;

    private Button btnBindAIDLService;

    private TextView textView;

    private ServiceConnection serviceConnection = new ServiceConnection() {

 

       @Override

       public void onServiceConnected(ComponentName name, IBinder service) {

           myService = IMyService.Stub.asInterface(service);

           btnInvokeAIDLService.setEnabled(true);

 

       }

 

       @Override

       public void onServiceDisconnected(ComponentName name) {

           // TODO Auto-generated method stub

 

       }

    };

 

    @Override

    public void onClick(View view) {

       switch (view.getId()) {

       case R.id.btnBindAIDLService:

           bindService(new Intent("net.blogjava.mobile.aidl.IMyService"),

                  serviceConnection, Context.BIND_AUTO_CREATE);

           break;

 

       case R.id.btnInvokeAIDLService:

           try {

              textView.setText(myService.getValue());

           } catch (Exception e) {

 

           }

           break;

       }

 

    }

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService);

       btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService);

       btnInvokeAIDLService.setEnabled(false);

       textView = (TextView) findViewById(R.id.textview);

       btnInvokeAIDLService.setOnClickListener(this);

       btnBindAIDLService.setOnClickListener(this);

    }

}

;