遠程服務
爲了使其他的應用程序也可以訪問本應用程序提供的服務,Android系統採用了遠程過程調用(Remote Procedure Call,RPC)方式來實現。與很多其他的基於RPC的解決方案一樣,Android使用一種接口定義語言(Interface Definition Language,IDL)來公開服務的接口。我們知道4個Android應用程序組件中的3個(Activity、BroadcastReceiver和ContentProvider)都可以進行跨進程訪問,另外一個Android應用程序組件Service同樣可以。因此,可以將這種可以跨進程訪問的服務稱爲AIDL(Android Interface Definition Language)服務。.
綁定遠程服務
public class RemoveService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return new MyBind();
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.e("remoteService", "遠程服務創建了");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e("remoteService", "遠程服務銷燬了");
}
private void sayHello() {
Log.e("remote", "hello");
}
public class MyBind extends IService.Stub {
public void callMethodInService() {
sayHello();
}
}
}
package com.example.remoteservice;
interface IService {
void callMethodInService();
}
public static abstract class Stub extends android.os.Binder implements com.example.remoteservice.IService
{
private static final java.lang.String DESCRIPTOR = "com.example.remoteservice.IService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
看到裏面正有suub類,而且已經幫我們繼承Binder並實現IService了~最後在AndroidManifest.xml文件裏爲該服務定義一個action,方便遠程調用該service。
<service android:name="com.example.remoteservice.RemoveService">
<intent-filter>
<action android:name="com.javy.remoteService"/>
</intent-filter>
</service>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical"
tools:context="com.example.bindremoteservice.MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bind"
android:text="綁定遠程服務"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/unbind"
android:text="解除綁定遠程服務"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/call"
android:text="調用遠程服務的方法"
/>
</LinearLayout>
佈局很簡單~也不用看了~package com.example.bindremoteservice;
import com.example.remoteservice.IService;
import android.app.Activity;
import android.content.ComponentName;
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.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private Button bind;
private Button unbind;
private Button call;
private MyConn conn;
private IService is;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
bind = (Button) findViewById(R.id.bind);
unbind = (Button) findViewById(R.id.unbind);
call = (Button) findViewById(R.id.call);
bind.setOnClickListener(this);
unbind.setOnClickListener(this);
call.setOnClickListener(this);
conn = new MyConn();
}
@Override
public void onClick(View v) {
if (v.equals(bind)) {
Intent intent = new Intent();
intent.setAction("com.javy.remoteService");
intent.setPackage("com.example.remoteservicedemo");
bindService(intent, conn, BIND_AUTO_CREATE);
}
if (v.equals(unbind)) {
unbindService(conn);
}
if (v.equals(call)) {
try {
is.callMethodInService();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("bindlog", "已綁定");
is = IService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("", "已解綁");
}
}
}
嗯~挺長的代碼~其實也很簡單~忽略掉findViewById,忽略掉setOnclickListener剩下的代碼也不多了。
if (v.equals(bind)) {
Intent intent = new Intent();
intent.setAction("com.javy.remoteService");
intent.setPackage("com.example.remoteservicedemo");
bindService(intent, conn, BIND_AUTO_CREATE);
}
綁定的操作與綁定本地服務的操作差不多,不過也就是多了個setAction與setPackage。is = IService.Stub.asInterface(service);
(留意剛纔的代碼哪些地方有log)現在筆者點擊綁定遠程服務: