Android IntentService
2015-12-12 16:05
387 查看
/**
*
* 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50274211
* @author:【JunTao_sun】
*
*
*/
IntentService是Service的子类,是一个通过Context.startService(Intent)启动,
以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的
onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候).
所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),
一次只能执行一个请求.
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}ServiceHandler是IntentService的内部类 是handler的子类
当有消息被加入消息队列 handlemessage会调用OnHandleIntent函数 处理intent
stopself(int startID) 不同于stopself()会直接停止服务 带参数的它会匹配startID是否一致 再停止服务。
如果同时有多个服务启动请求发送到onStartCommand(),不应该在处理完一个请求后调用stopSelf();
因为在调用此函数销毁service之前,可能service又接收到新的启动请求,如果此时service被销毁,
新的请求将得不到处理。此情况应该调用stopSelf(int startId)。
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
在Oncreate方法中 初始化线程HandlerThread 并开始启动 。
初始化ServiceHandler。得到HandlerThread 里的消息轮询器 。
把mServiceLooper消息轮询器
做参数构造一个hanler对象 也就是初始化ServiceHandler。
下边是HandlerThread 和looper的源码
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}looper的:
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
} HandlerThread 的run方法 里调用 Looper.prepare(); 由源码可知 sThreadlocal 是成员变量 ThreadLocal类 相当于map变量副本,
如果sThreadlocal 已经有looper了 抛异常 ->一个线程只能有一个looper ,没有则存储在sThreadlocal 。
接着 HandlerThread 里调用looper的静态方法 获得looper.,
public static Looper myLooper() {
return sThreadLocal.get();
}
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
} new ServiceHandler(mServiceLooper) 会调用hanler的三个构造方法
关联一个消息轮询器 此时处理消息的就是HanlerhThread的消息轮询器里的message.
继续回到IntentService的源码
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在o
4000
nStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值是四个常量分别是:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}设置是否重新发送意图,当服务被异常Kill掉的时候
onStartCommand 方法中 调用了onStart函数:
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
onStart()方法 把消息发送到 ServiceHandler 处理意图 和是否停止服务
不能重写onStartCommand方法
如果想要对意图进行处理可以 重写onHandleIntent(Intent intent)方法
*
* 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50274211
* @author:【JunTao_sun】
*
*
*/
IntentService是Service的子类,是一个通过Context.startService(Intent)启动,
以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的
onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候).
所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),
一次只能执行一个请求.
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}ServiceHandler是IntentService的内部类 是handler的子类
当有消息被加入消息队列 handlemessage会调用OnHandleIntent函数 处理intent
stopself(int startID) 不同于stopself()会直接停止服务 带参数的它会匹配startID是否一致 再停止服务。
如果同时有多个服务启动请求发送到onStartCommand(),不应该在处理完一个请求后调用stopSelf();
因为在调用此函数销毁service之前,可能service又接收到新的启动请求,如果此时service被销毁,
新的请求将得不到处理。此情况应该调用stopSelf(int startId)。
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
在Oncreate方法中 初始化线程HandlerThread 并开始启动 。
初始化ServiceHandler。得到HandlerThread 里的消息轮询器 。
把mServiceLooper消息轮询器
做参数构造一个hanler对象 也就是初始化ServiceHandler。
下边是HandlerThread 和looper的源码
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}looper的:
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
} HandlerThread 的run方法 里调用 Looper.prepare(); 由源码可知 sThreadlocal 是成员变量 ThreadLocal类 相当于map变量副本,
如果sThreadlocal 已经有looper了 抛异常 ->一个线程只能有一个looper ,没有则存储在sThreadlocal 。
接着 HandlerThread 里调用looper的静态方法 获得looper.,
public static Looper myLooper() {
return sThreadLocal.get();
}
public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }HandlerThread 里有个while 循环 当前线程是活的并mlooper是Null 阻塞 ,等待到mlooper不等于Null返回。
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
} new ServiceHandler(mServiceLooper) 会调用hanler的三个构造方法
关联一个消息轮询器 此时处理消息的就是HanlerhThread的消息轮询器里的message.
继续回到IntentService的源码
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在o
4000
nStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值是四个常量分别是:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}设置是否重新发送意图,当服务被异常Kill掉的时候
onStartCommand 方法中 调用了onStart函数:
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
onStart()方法 把消息发送到 ServiceHandler 处理意图 和是否停止服务
不能重写onStartCommand方法
如果想要对意图进行处理可以 重写onHandleIntent(Intent intent)方法
相关文章推荐
- Android 获取签名公钥 和 公钥私钥加解密
- Android乐动力的开始启动页面开源代码
- Android IntentService的使用与源码解析
- Android Fragment 你应该知道的一切
- Android Studio 教程
- Android Studio错误:failed to complete gradle execution
- Android正在使用Handler实现信息发布机制(一)
- activity和view判断滑动
- Shared library "Hello World!" for Android
- Android编程之SDK安装组件的离线安装方法分享
- Android应用内多进程的使用
- Android中Settings.System的使用
- Android 提升进入界面的速度
- 每个android开发者都应该知道的Top 5三方库(2015版)
- Android碎片使用
- Android: JNI本地函数控制Java端代码
- android - Notifications
- android设备终端与蓝牙模块(HC-06)的通讯编程思路
- 《AndroidStudio每日一贴》10. 选择查找结果
- Android MotionEvent传递流程 源码笔记