如果需要访问不同进程间service中的数据或者方法,需要使用AIDL(android interface description language)工具,可以通过如下方法:
public boolean bindService(Intent intent, ServiceConnection conn, int flags) ;
public void unbindService(ServiceConnection conn);
intent是跳转到service的intent,conn是与service连接状态的类。如果想要访问service中的数据,可以在onServiceConnected()方法中进行实现。
如果另外一个进程想访问上图Myservice.java中getruntimeinfo()方法
1 public String getruntimeinfo(){ 2 String info = "momory usage 5%"; 3 return info; 4 }
则需要以下步骤:
1,新建一个interface
1 package com.example.day16_04remoteservicedemo; 2 3 public interface MyRemoteService { 4 public String forworadgetruntimeinfo(); 5 }
2,到源程序目录下找到MyRemoteService.java,直接将后缀名改为.aidl并保存
3,刷新project,可看到eclipse中报错
4,去掉public,保存;可看到在gen下自动生成MyRemoteService.java
5,在MyService.java中继承MyRemoteService.java中的Stub类
1 class RemoteBinder extends Stub{ 2 @Override 3 public String forworadgetruntimeinfo() throws RemoteException { 4 return getruntimeinfo(); 5 } 6 }
6,在AndroidManifest.xml中配置service
1 <service android:name=".MyService"> 2 <intent-filter> 3 <action android:name="com.cskaoyan.service" /> 4 </intent-filter> 5 </service>
被访问的service源代码如下:
1 package com.example.day16_04remoteservicedemo; 2 3 import com.example.day16_04remoteservicedemo.MyRemoteService.Stub; 4 import android.app.Service; 5 import android.content.Intent; 6 import android.os.IBinder; 7 import android.os.RemoteException; 8 9 public class MyService extends Service { 10 IBinder binder ; 11 @Override 12 public IBinder onBind(Intent intent) { 13 // TODO Auto-generated method stub 14 System.out.println("MyService.onBind()"); 15 //当且仅当此处返回一个非空的Ibinder对象时,bindservice一端的Connection内的onserviceConnected函数才会被系统call到 16 return new RemoteBinder(); 17 } 18 19 public String getruntimeinfo(){ 20 String info = "momory usage 5%"; 21 return info; 22 } 23 24 @Override 25 public boolean onUnbind(Intent intent) { 26 // TODO Auto-generated method stub 27 System.out.println("MyService.onUnbind()"); 28 return super.onUnbind(intent); 29 } 30 31 @Override 32 public void onRebind(Intent intent) { 33 // TODO Auto-generated method stub 34 super.onRebind(intent); 35 System.out.println("MyService.onRebind()"); 36 } 37 38 @Override 39 public void onCreate() { 40 // TODO Auto-generated method stub 41 super.onCreate(); 42 System.out.println("MyService.onCreate()"); 43 } 44 45 @Override 46 public void onDestroy() { 47 // TODO Auto-generated method stub 48 super.onDestroy(); 49 System.out.println("MyService.onDestroy()"); 50 } 51 52 class RemoteBinder extends Stub{ 53 @Override 54 public String forworadgetruntimeinfo() throws RemoteException { 55 // TODO Auto-generated method stub 56 return getruntimeinfo(); 57 } 58 } 59 }
MyRemoteService.aidl
1 package com.example.day16_04remoteservicedemo; 2 3 interface MyRemoteService { 4 String forworadgetruntimeinfo(); 5 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.day16_04remoteservicedemo" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="14" 9 android:targetSdkVersion="21" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <service android:name=".MyService"> 17 <intent-filter> 18 <action android:name="com.cskaoyan.service" /> 19 </intent-filter> 20 </service> 21 </application> 22 23 </manifest>
然后再来写客户端:
将com.example.day16_04remoteservicedemo下的MyRemoteService.aidl直接拷贝过来,放置位置如下图:
最重要的一步是如何在OnServiceConnected方法中得到一个IBinder对象
1 class MyConnection implements ServiceConnection{ 2 3 @Override 4 public void onServiceConnected(ComponentName name, IBinder service) { 5 //binder= (Stub) service;不可行 6 //因为绑定远程Service的ServiceConnection并不能直接获取Service的OnBind() 7 //方法返回的对象,它只能返回OnBind()方法所返回的对象的代理 8 myRemoteService = MyRemoteService.Stub.asInterface(service); 9 // TODO Auto-generated method stub 10 System.out.println("MainActivity.MyConnection.onServiceConnected()"); 11 }
源代码如下:
1 package com.example.day16_05otherapplication; 2 3 import com.example.day16_04remoteservicedemo.MyRemoteService; 4 import android.app.Activity; 5 import android.content.ComponentName; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.content.ServiceConnection; 9 import android.os.Bundle; 10 import android.os.IBinder; 11 import android.os.RemoteException; 12 import android.view.View; 13 14 public class MainActivity extends Activity { 15 16 MyConnection conn; 17 MyRemoteService myRemoteService; 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_main); 23 } 24 25 public void bindservice(View v){ 26 Intent intent = new Intent(); 27 intent.setAction("com.cskaoyan.service"); 28 conn=new MyConnection(); 29 bindService(intent, conn, Context.BIND_AUTO_CREATE); 30 31 } 32 public void unbindservice(View v){ 33 unbindService(conn); 34 conn=null; 35 } 36 37 public void remotecall(View v) throws RemoteException{ 38 System.out.println(myRemoteService.forworadgetruntimeinfo()); 39 String info = myRemoteService.forworadgetruntimeinfo(); 40 System.out.println("MainActivity.remotecall()"+info); 41 } 42 43 @Override 44 protected void onDestroy() { 45 // TODO Auto-generated method stub 46 super.onDestroy(); 47 if (conn!=null) { 48 unbindService(conn); 49 } 50 } 51 52 class MyConnection implements ServiceConnection{ 53 54 @Override 55 public void onServiceConnected(ComponentName name, IBinder service) { 56 //binder= (Stub) service;不可行 57 //因为绑定远程Service的ServiceConnection并不能直接获取Service的OnBind() 58 //方法返回的对象,它只能返回OnBind()方法所返回的对象的代理 59 myRemoteService = MyRemoteService.Stub.asInterface(service); 60 // TODO Auto-generated method stub 61 System.out.println("MainActivity.MyConnection.onServiceConnected()"); 62 } 63 64 @Override 65 public void onServiceDisconnected(ComponentName name) { 66 // TODO Auto-generated method stub 67 System.out.println("MainActivity.MyConnection.DisConnected()"); 68 } 69 } 70 }
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="com.example.day16_05otherapplication.MainActivity" 10 android:orientation="vertical" > 11 12 <TextView 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:text="@string/hello_world" /> 16 17 <Button 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:text="绑定服务" 21 android:onClick="bindservice"/> 22 23 <Button 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:text="解除绑定" 27 android:onClick="unbindservice" /> 28 <Button 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:text="调用远程的方法" 32 android:onClick="remotecall"/> 33 </LinearLayout>
当点击“绑定服务后”,再点击“调用远程的方法”,就可以获取MyService.java中 getruntimeinfo()方法中的String “momory usage 5%”