Service的一个小例子
2016-02-24 09:52
441 查看
1、不与其他组件交互,纯本地的一个服务(可以不看)
java代码:
Activity类,用于启动服务:
Service的子类:
在AndroidManifest.xml中把服务添加进去:
在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
在main.xml中,添加3个button,
Application 2:
有两个文件:
ServiceTest4Activity:
MyService.java
在AndroidManifest.xml中,
点击绑定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:
还有一个Activity:AIDLTest1Activity
其AndroidManifest.xml
工程2:客户端,把刚才工程1的gen下面的com.aidltest1包复制到工程2的res目录下,
现在工程2包含了两个包,com.aidltest1,com.aidl.test2
其中,com.aidl.test2包含AidlClientTest2Activity
在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端的数据。
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端的数据。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- android之定时器AlarmManager
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序