Android四大组件之Service
2016-05-11 18:42
741 查看
Service
基本概念
Service是Android系统中的四大组件之一, 它跟Activity的级别差不多, 但不能自己运行只能后台运行, 并且可以和其他组件进行交互。Service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。Service的生命周期
onStartComand的返回参数
启动和停止一个Service
//启动一个服务 Intent intent = new Intent(this, MyService.class); startService(intent); //停止一个服务 Intent intent = new Intent(this, MyService.class); stopService(intent);
Note:
started service:
1, 服务同时只会被创建一次,可以通过外部调用stopServic或者调用stopSelf终止自己的服务
2, 当执行一个以启动的服务,会直接调用onStartCommand方法来执行业务
3, 默认情况下服务与主线程同一个进程中的同一个线程中执行,如果执行一个比较耗时的操作,我们必须使用子线程完成工作, 避免主线程被阻塞
4, 使用started Service启动的一个服务在没有关闭之前会一直在后台运行!
IntentService
Note:
1, 内部有一个工作线程完成耗时操作, 只需要实现onHandleIntent()方法即可
2,完成工作后停止服务
3,同时执行多个任务时,会以工作队列的方式依次执行
4, 通常使用该类完成本App的耗时工作
public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { System.out.println(intent.getStringExtra("info")); for (int i = 0; i < 20; i++) { System.out.println("onHandleIntent " + i + " " + Thread.currentThread().getName()); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Bind Service
Note:
绑定服务:
通过绑定服务来实现功能的步骤:
1, 客户端通过bindService方法来绑定一个服务对象, 如果绑定成功, 会回调ServiceConnection接口中的onServiceConnected
2, 通过Service组件来暴露业务接口
3, 服务端通过创建一个*.aidl文件, 来定义一个可以被客户端调用的业务接口
一个aidl文件:
(1) 不能有修饰符, 类似接口的写法
(2) 支持的类型有8种基本数据类型和 String CharSequence, List, Map, 自定义类型
自定义类型要实现Parcelable接口
定义一个aidl文件声明该类型
在其他aidl文件中使用, 必须要使用import
4, 服务端需要提供一个业务接口的实现类, 通常会extends Stub类
5, 通过Service的onBind方法返回被绑定的方法
6, 客户端如果绑定chenggong,就可以像调用自己的方法一样调用远程的业务对象方法
使用技巧
started启动的服务会长期存在, 只要不停
bind启动的服务通常会在解锁时停止
通常情况下, 先started, 后bind
服务端代码
package com.lulu.admin.lservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyBoundService extends Service { public MyBoundService() { } @Override public void onCreate() { super.onCreate(); } //绑定 @Override public IBinder onBind(Intent intent) { return new CatImpl(); } //解除绑定 @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); } }
客户端代码
MainActivity.java
private ICat cat; private boolean mBound = false;//是否绑定
//绑定服务的连接回调接口 private ServiceConnection conn = new ServiceConnection() { //绑定成功后返回的方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { //得到cat对象 cat = ICat.Stub.asInterface(service); mBound = true; Toast.makeText(MainActivity.this, "绑定成功", Toast.LENGTH_SHORT).show(); } @Override public void onServiceDisconnected(ComponentName name) { //服务异常时调用, 很少使用 mBound = false; } }; //绑定一个服务 public void boundClick(View view) { Intent intent = new Intent(this, MyBoundService.class); //异步绑定, 立即返回! //绑定成功后会回调onServiceConnected!!!!!! bindService(intent, conn, Context.BIND_AUTO_CREATE); //如果没有创建就自动创建,如果创建了就不用了 } //解绑的方法 public void unBoundClick(View view) { if (mBound) { unbindService(conn); Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show(); mBound = false; } } // public void callClick(View v) { if (cat == null) { return; } try { cat.setName("喵猫"); Toast.makeText(MainActivity.this, cat.desc() + " " + cat.getPerson().toString(), Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } }
Person.java
package com.lulu.admin.lservice; import android.os.Parcel; import android.os.Parcelable; /** * Created by Admin on 2016/5/18. */ public class Person implements Parcelable{ String name; String works; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", works='" + works + '\'' + '}'; } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() { public Person createFromParcel(Parcel in) { Person p = new Person(); p.name = in.readString(); p.works = in.readString(); return p; } public Person[] newArray(int size) { return new Person[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(works); } }
CatImp.java
package com.lulu.admin.lservice; import android.os.RemoteException; /** * 业务接口的具体实现类 * Created by Admin on 2016/5/18. * Stub是IBind的子类或者说是实现 */ public class CatImpl extends ICat.Stub { private String name; @Override public void setName(String name) throws RemoteException { this.name = name; } @Override public String desc() throws RemoteException { return "hello my is" + name + ", I am a Cat"; } @Override public Person getPerson() throws RemoteException { Person p = new Person(); p.name = "小次郎"; p.works = "强盗"; return p; } @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } }
AIDL文件
ICat.aidl
// ICat.aidl package com.lulu.admin.lservice; import com.lulu.admin.lservice.Person; // Declare any non-default types here with import statements interface ICat { void setName(String name); String desc(); Person getPerson();//获取当前猫的主任 /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); }
Person.aidl
// Person.aidl package com.lulu.admin.lservice; parcelable Person;
Messenger
让我们来大致说一下创建步骤
服务端
1, 首先创建一个handler,需要Service处理的代码在这里处理
2, 创建一个Messenger对象, 传入handler
3, 在onBind方法中返回由Messenger得到的Binder对象
public class MessengerService extends Service { public static final int SAY_HELLO = 0x1; public MessengerService() { } @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SAY_HELLO: String info = (String) msg.obj; Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show(); break; } } }; private Messenger messenger = new Messenger(handler); }
客户端
我引用了API文档中的注释, 过程跟跟前面的讲述的绑定服务差不多
//首先声明一个Messenger private Messenger mService = null; private boolean mBound2 = false; @Override protected void onStart() { super.onStart(); //绑定Messenger服务 bindService(new Intent(this, MessengerService.class), conn2, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); if(mBound2){ unbindService(conn2); mBound2 = false; Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show(); } } //使用Messenger方法, 绑定服务的连接回调接口 private ServiceConnection conn2 = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. //创建一个Messenger对象传入IBinder的对象 mService = new Messenger(service); mBound2 = true; } @Override public void onServiceDisconnected(ComponentName name) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mService = null; mBound2 = false; } }; //使用Messenger方法 public void messengerClick(View v) { if(!mBound2){ return; } // Create and send a message to the service, using a supported 'what' value Message msg = Message.obtain(); msg.what = MessengerService.SAY_HELLO; msg.obj = "你好啊"; try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } }
Demo下载地址: http://download.csdn.net/download/u013144863/9524589
以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析