1、不与其他组件交互,纯本地的一个服务(可以不看)
java代码:
Activity类,用于启动服务:
package com.service.test1;
//import android.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
import android.util.Log;
public class ServiceTest1Activity extends Activity {
/** Called when the activity is first created. */
private Button btn1;
private Button btn2;
private String TAG = "ServiceTest1Activity";
private Intent intent;
//=new Intent(ServiceTest1Activity.this,Service1.class);;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn1.setOnClickListener(listener1);
btn2.setOnClickListener(listener1);
intent= new Intent(ServiceTest1Activity.this,Service1.class);
}
private OnClickListener listener1 = new OnClickListener() {
public void onClick(View v) {
Log.v(TAG, "######onClick;.....");
// TODO Auto-generated method stub
if (v.getId() == R.id.btn1) {
startService(intent);
Log.v(TAG, "######startservice;.....");
} else if (v.getId() == R.id.btn2) {
stopService(intent);
Log.v(TAG, "######stopservice;.....");
}
}
};
}
Service的子类:
package com.service.test1;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class Service1 extends Service {
private String TAG="Service1";
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG,"#####onBind");
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v(TAG,"#####onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v(TAG,"#####onDestroy");
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
Log.v(TAG,"#####onStart");
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(TAG,"#####onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
Log.v(TAG,"#####onRebind");
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG,"#####onUnbind");
return super.onUnbind(intent);
}
}
在AndroidManifest.xml中把服务添加进去:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.service.test1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name=".ServiceTest1Activity"
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=".Service1"/>
</application>
</manifest>
在main.xml中添加几个button,略。。
运行结果:
onClick
startservice
onCreate
onStartCommand
onStart
再次点击“开始服务”button,
onClick
startservice
onStartCommand
onStart
一直循环执行这个,也就是只有第一次才会onCreate,在没有销毁之前,再启动只会执行
onStartCommand
onStart
点击停止,
onClick,stopservice,onDestroy
只stop一次,再点击也不会执行onDestroy了。
2、一个Application 1启动另一个Application 2的Service,不从2获取数据
Application 1
package com.myservice.test3;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
//import com.myservice.test4;
//bindService,unBindService
public class ServiceTest3Activity extends Activity {
/** Called when the activity is first created. */
private Button btn1;
private Button btn2;
private Button btn3;
private String TAG = "ServiceTest3Activity";
private Intent intent;
// 返回从Service中获取的数据
//private MyService.MyBinder binder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn1.setOnClickListener(listener1);
btn2.setOnClickListener(listener1);
btn3.setOnClickListener(listener1);
}
private OnClickListener listener1 = new OnClickListener() {
public void onClick(View v) {
Log.v(TAG, "######onClick;.....");
// TODO Auto-generated method stub
intent = new Intent();
// intent.setClassName(packageContext, className)
// 隐式用intent
intent.setAction("bindsususervice");
if (v.getId() == R.id.btn1) {
bindService(intent, sconnection, Context.BIND_AUTO_CREATE);
// bindSerivce(Intent service,ServiceConnection conn,int flags)
// Intent:通过该参数也就是Intent我们可以启动指定的Service
// flags:指定绑定时是否自动创建Service
/*
* ServiceConnection:该参数是一个ServiceConnection对象,这个对象用于监听访问者(也可以说成是客户端
* )与Service之间的连接情况,
* 当访问者与Service连接成功时将回调ServiceConnection对象的onServiceConnected
* (ComponentName name,Ibinder service)方法;
* 如果断开将回调onServiceDisConnected(CompontName name)方法
*/
Log.v(TAG, "######bindService.....");
} else if (v.getId() == R.id.btn2) {
unbindService(sconnection);
Log.v(TAG, "######unbindService.....");
} else if (v.getId() == R.id.btn3) {
/*Toast.makeText(this, "Service的count值为" + binder.getCount(),
Toast.LENGTH_LONG).show();*/
}
}
};
private ServiceConnection sconnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.v(TAG, "######onServiceConnected.....");
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.v(TAG, "######onServiceDisconnected.....");
}
};
}
在main.xml中,添加3个button,
Application 2:
有两个文件:
ServiceTest4Activity:
package com.myservice.test4;
import android.app.Activity;
import android.os.Bundle;
public class ServiceTest4Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
MyService.java
package com.myservice.test4;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static String TAG="MyService";
private int count=4;
private boolean quit;
// private MyBinder binder = new MyBinder();
// 新建一个Binder对象用于提供给客户端
/* public class MyBinder extends Binder{
public int getCount(){
return count;
}
}*/
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.v(TAG, "#####onBind");
// 返回给客户端一个Binder对象
//return binder;
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "#####onCreate");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.v(TAG, "#####onDestroy");
}
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
Log.v(TAG, "#####onRebind");
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.v(TAG, "#####onStart");
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG, "#####onUnbind");
return super.onUnbind(intent);
}
}
在AndroidManifest.xml中,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myservice.test4"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ServiceTest4Activity"
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=".MyService" >
<intent-filter>
<action android:name="bindsususervice" />
<!-- action android:name= "bind susu service"></action> -->
</intent-filter>
</service>
</application>
</manifest>
点击绑定button,
绑定
01-30 12:28:01.021: V/AidlClientTest2Activity(8247): ######onClick;.....
01-30 12:28:01.041: V/AidlClientTest2Activity(8247): ######bindService.....
01-30 12:28:01.072: V/MyService(8315): ######onCreate()
01-30 12:28:01.082: V/MyService(8315): ######onBind()
点击取消绑定button
取消绑定服务
01-30 12:28:28.413: V/AidlClientTest2Activity(8247): ######onClick;.....
01-30 12:28:28.421: V/MyService(8315): ######onDestroy()
01-30 12:28:28.441: V/AidlClientTest2Activity(8247): ######unbindService.....
问题:不能从Application 1import Application 2 的类,不能在ServiceTest3Activity中import com.myservice.test4.MyService;也就不能访问从MyService中获取数据!!
解决办法,用AIDL
见下例:
包括两个工程:
工程1:服务器端:AIDLTest1工程,在src的com.aidltest1包下,new file,ISuService.aidl,然后写入
package com.aidltest1;
interface ISuService{
String getValue();
}
然后build,
发现在gen里面生成com.aidltest1包,包含ISuService.java,R.java
然后新建MyService:
package com.aidltest1;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v("MyService", "######onBind()");
// onBind()方法必须返回MyServiceImpl的对象实例,否则客户端无法获取Service对象。
return new MyServiceImpl();
}
public class MyServiceImpl extends ISuService.Stub {
public String getValue() throws RemoteException {
// TODO Auto-generated method stub
Log.v("MyService", "######getValue()");
return "#########impl";
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v("MyService", "######onCreate()");
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v("MyService", "######onDestroy()");
super.onDestroy();
}
}
还有一个Activity:AIDLTest1Activity
package com.aidltest1;
import android.app.Activity;
import android.os.Bundle;
public class AIDLTest1Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
其AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aidltest1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AIDLTest1Activity"
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=".MyService">
<intent-filter>
<action android:name="srx.ISuService"/>
</intent-filter>
</service>
</application>
</manifest>
工程2:客户端,把刚才工程1的gen下面的com.aidltest1包复制到工程2的res目录下,
现在工程2包含了两个包,com.aidltest1,com.aidl.test2
其中,com.aidl.test2包含AidlClientTest2Activity
package com.aidl.test2;
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的包
import com.aidltest1.ISuService;
;
public class AidlClientTest2Activity extends Activity {
/** Called when the activity is first created. */
private Button btn1;
private Button btn2;
private Button btn3;
private Intent intent;
private static String TAG = "AidlClientTest2Activity";
// private
ISuService suService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn1.setOnClickListener(listener1);
btn2.setOnClickListener(listener1);
btn3.setOnClickListener(listener1);
}
private OnClickListener listener1 = new OnClickListener() {
public void onClick(View v) {
Log.v("AidlClientTest2Activity", "######onClick;.....");
// TODO Auto-generated method stub
intent = new Intent();
// intent.setClassName(packageContext, className)
// 这个action是客户端用于访问AIDL服务的ID
intent.setAction("srx.ISuService");
if (v.getId() == R.id.btn1) {
bindService(intent, sconnection, Context.BIND_AUTO_CREATE);
Log.v(TAG, "######bindService.....");
} else if (v.getId() == R.id.btn2) {
unbindService(sconnection);
Log.v(TAG, "######unbindService.....");
} else if (v.getId() == R.id.btn3) {
try {
String s = suService.getValue();
Log.v(TAG, "s===" + s);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
private ServiceConnection sconnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.v(TAG, "######onServiceConnected.....");
suService = ISuService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.v(TAG, "######onServiceDisconnected.....");
}
};
}
在main.xml中新建3个button即可。
运行结果:
绑定
01-30 12:28:01.021: V/AidlClientTest2Activity(8247): ######onClick;.....
01-30 12:28:01.041: V/AidlClientTest2Activity(8247): ######bindService.....
01-30 12:28:01.072: V/MyService(8315): ######onCreate()
01-30 12:28:01.082: V/MyService(8315): ######onBind()
01-30 12:28:01.101: V/AidlClientTest2Activity(8247): ######onServiceConnected.....
获取数据
01-30 12:28:13.902: V/AidlClientTest2Activity(8247): ######onClick;.....
01-30 12:28:13.902: V/MyService(8315): ######getValue()
01-30 12:28:13.902: V/AidlClientTest2Activity(8247): s===#########impl
取消绑定服务
01-30 12:28:28.413: V/AidlClientTest2Activity(8247): ######onClick;.....
01-30 12:28:28.421: V/MyService(8315): ######onDestroy()
01-30 12:28:28.441: V/AidlClientTest2Activity(8247): ######unbindService.....
总结:
AIDL流程(在不同的Application中,前者想调用后者的Service端的方法)
Application 1:客户端
1、 Intent intent = new Intent();
2、 bindService(intent, conn, Context.BIND_AUTO_CREATE);
客户端先绑定服务。
Application 2:Service端
3、 新建AIDL,build,在Service子类中实现此AIDL。
4、 onBind()中 -----return IBinder对象(实际返回实现了AIDL类的那个类对象)------->
Application 1:客户端
5、把Service端build生成的aidl对应的java包拷到客户端src下
6、conn对象的onServiceConnected(ComponentName name,IBinder service)方法,
--> 通过传递过来的Binder对象(参数service)-->获取Service中数据。
“客户端”如果想获得“服务器端”的“数据”,必须用AIDL,在Service端的onBind()中返回AIDL对象,在 客户端的onServiceConnected中获取这个返回的AIDL对象,然后就可以通过这个AIDL对象调用它的被实现了的抽象方法,通过这个抽象方法获取Service端的数据。