针对Service写了一个demo,程序中有注释,其中包括进程间通信,AIDL,Activity与Service之间的关联绑定等,demo主要模拟远程Service用法
package com.alipay.servicetest;
//在此aidl文件中定义Activity需要与Service进行通信的方法
interface MyAIDLService{
int plus(int a, int b);
String toUpperCase(String str);
}
/**
* Alipay.com Inc.
* Copyright (c) 2004-2015 All Rights Reserved.
*/
package com.alipay.servicetest;
import com.alipay.servicetest.MyAIDLService.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/**在此处实现我们刚刚定义好的MyAIDLService接口
*
* @author quyang.ybb
* @version $Id: MyService.java, v 0.1 2015年10月17日 下午9:18:14 quyang.ybb Exp $
*/
public class MyService extends Service {
public static final String TAG = "MyService";
@Override
public void onCreate() {
Log.d(TAG, "onCreate() executed");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy() executed");
super.onDestroy();
}
/**
* @see android.app.Service#onBind(android.content.Intent)
*/
//onBind()方法用于和Activity建立关联
//在onBind()方法中将MyAIDLService.Stub的实现返回。这里为什么可以
//这样写呢?因为Stub其实就是Binder的子类,所以在onBind()方法中可以直接返回Stub的实现。
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind() executed");
return mBinder;
}
MyAIDLService.Stub mBinder = new Stub() {
@Override
public String toUpperCase(String str) throws RemoteException {
Log.d(TAG, "toUpperCase() executed");
if(str!=null){
return str.toUpperCase();
}
return null;
}
@Override
public int plus(int a, int b) throws RemoteException {
Log.d(TAG, "plus() executed");
return a+b;
}
};
}
package com.alipay.servicetest;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
public static final String TAG = "MainActivity";
private Button startService;
private Button stopService;
private Button bindService;
private Button unbindService;
private MyAIDLService myAIDLService;
//创建了一个ServiceConnection的匿名类,重写onServiceDisconnected和onServiceConnected方法
private ServiceConnection connection = new ServiceConnection() {
//onServiceDisconnected()会在Activity和Service解除关联的时候调用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//onServiceConnected()会在Activity和Service建立关联的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected() executed");
// 通过MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成MyAIDLService对象
// 有了MyAIDLService的实例,Activity和Service之间的关系就变得非常紧密,可以在Activity中
// 根据具体的场景来调用MyAIDLService中的任何方法,即实现了Acticity指挥Service干什么Service
// 就去干什么的功能
myAIDLService = MyAIDLService.Stub.asInterface(service);
//调用在MyAIDLService.aidl文件中定义的所有接口
try {
int result = myAIDLService.plus(3, 5);
String upperStr = myAIDLService.toUpperCase("quyang");
Log.d(TAG, "result is " + result);
Log.d(TAG, "upperStr is " + upperStr);
} catch (Exception e) {
e.printStackTrace();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.start_service);
stopService = (Button) findViewById(R.id.stop_service);
bindService = (Button) findViewById(R.id.bind_service);
unbindService = (Button) findViewById(R.id.unbind_service);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
//onCreate()方法只会在Service第一次被创建的时候调用,如果当前
//Service已经被创建过了,不管怎样调用startService()方法,onCreate()
//方法都不会再执行。因此你可以再多点击几次start service按钮试一次,
//每次都只会有onStartCommand()方法中的打印日志。
startService(startIntent);
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);
break;
case R.id.bind_service:
Intent bindIntent = new Intent(this, MyService.class);
// Activity和Service的关联是在BindService按钮的点击事件里完成的,通过调用bindService()方法
//将Activity和Service进行绑定,三个入参,BIND_AUTO_CREATE表示在Activity和Service建立关联
//后自动创建Service,这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
bindService(bindIntent, connection, BIND_AUTO_CREATE);
break;
case R.id.unbind_service:
//解除Activity和Service之间的关联
unbindService(connection);
break;
default:
break;
}
}
}
<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">
<Button
android:id="@+id/start_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="start service" />
<Button
android:id="@+id/stop_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="stop service" />
<Button
android:id="@+id/bind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="bind service" />
<Button
android:id="@+id/unbind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="unbind service" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alipay.servicetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.alipay.servicetest.MyService"
android:process=":remote" >
<intent-filter>
<action android:name="com.alipay.servicetest.MyAIDLService" />
</intent-filter>
</service>
</application>
</manifest>
package com.alipay.aidlclient;
import com.alipay.servicetest.MyAIDLService;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class AidlClientActivity extends Activity implements OnClickListener {
public static final String TAG = "AidlClientActivity";
private Button bindService;
private MyAIDLService myAIDLService;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected() executed");
myAIDLService = MyAIDLService.Stub.asInterface(service);
//调用在MyAIDLService.aidl文件中定义的所有接口
try {
int result = myAIDLService.plus(30, 50);
String upperStr = myAIDLService.toUpperCase("yangbeibei");
Log.d(TAG, "result is " + result);
Log.d(TAG, "upperStr is " + upperStr);
} catch (Exception e) {
e.printStackTrace();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService = (Button) findViewById(R.id.bind_service);
bindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent();
//有些时候我们使用Service的时需要采用隐式意图启动的方式,但是Android 5.0
//一出来后,其中有个特性就是Service Intent must be explicit,也就是说
//从Lollipop开始,service服务必须采用显式意图方式启动.
//指定启动的是哪个package应用中的action指向的服务组件
intent.setAction("com.alipay.servicetest.MyAIDLService");
intent.setPackage("com.alipay.servicetest");
bindService(intent, connection, BIND_AUTO_CREATE);
}
}
<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" >
<Button
android:id="@+id/bind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="bind service" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alipay.aidlclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".AidlClientActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
运行demo程序,观察LogCat中打印的日志可以看到已实现进程间的通信
在此介绍两篇关于Android Service的博客,概念清晰明了,本文的demo也是基于此实现并运行的,相信读者看过后关于Service的一切肯定能明白,记录是为以后回顾
http://blog.csdn.net/guolin_blog/article/details/11952435 http://blog.csdn.net/guolin_blog/article/details/9797169