
本文共 3138 字,大约阅读时间需要 10 分钟。
1、保证 service 不被杀掉
StartCommond 的几个常量参数简介:
a、START_STICKY
在运行 onStartCommand 后 service 进程被 kill 后将保留在开始状态,但是不保留传入的intent。
之后 service 就会再次尝试重新创建,因为保留在开始状态,在创建 service 后将保证调用 onstartCommand,如果没有传递任何开始命令给 service,那将获取到 null 的 intent。
b、START_NOT_STICKY
在运行 onStartCommand 后 service 进程被 kill 后,并且没有新的 intent 传递给它。
Service 将移出开始状态,并且直到新的方法(startService)调用才重新创建。
因为如果没有传递任何未决定的 intent 那么 service 是不会启动,也就是期间 onstartCommand 不会接收到任何 null 的 intent。
c、START_REDELIVER_INTENT
在运行 onStartCommand 后 service 进程被 kill 后,系统将会再次启动 service,并传入最后一个 intent 给 onstartCommand。
直到调用 stopSelf(int) 才停止传递 intent。如果在被 kill 后还有未处理好的 intent,那被 kill 后服务还是会自动启动。因此 onstartCommand 不会接收到任何 null 的 intent。
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) { flags = START_STICKY; return super.onStartCommand(intent, flags, startId);}
2、如何结束线程
a、stop 强制停止
Android 的线程类本身提供了一些公共方法去结束线程,但不安全不建议使用
final void stop();
b、线程里的 run 函数执行完后线程会自行销毁
c、手动停止
在 run 里设置标志先停止运行,再调用 Thread.interrupt()
注:在 run 没有停止时调用 Thread.interrupt() 是没有效果的
示例:
a、加入一个成员变量, 在程序的循环里轮流去检查这个变量,变量变化时,就会退出这个线程
public class StopThread extends Thread { private boolean _run = true; public void stopThread(boolean run) { this._run = !run; } @Override public void run() { while(_run) { // 相应处理 } }}
b、方法 a 虽然可以取消线程,但是在有阻塞线程语句的时候会存在问题
比如设计到 Socket 的阻塞语句,虽然 java 提供异步 io 但是异步 io 是在程序里不断去查询有没有消息,耗电量较大
Java interrupt()方法且该方法是安全的,该方法可以将阻塞的线程唤醒过来,但不能将非阻塞的线程中断
while(!this.isInterrupted()) { // 相应处理 }public static void main(String[] args) { StopThread thread=new StopThread(); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt(); System.out.println(interrupt);}
c、Android 在自己的 Api 中加入了 Process 类,可以直接结束进程,也就是当前线程所在的 JVM
final static void killProcess(int pid)
其中 pid 可以通过 Process.mypid() 获取,但这样终结的是整个程序
如果该线程处在不可中断状态下,就是没有调用上述 api,那么 java 只是设置一下该线程的 interrupt 状态,其他事情都不会发生,如果该线程之后会调用行数阻塞 API,那到时候线程会马会上跳出,并抛出 InterruptedException,接下来的事情就跟第一种状况一致了。如果不会调用阻塞 API,那么这个线程就会一直执行下去。
readCacheThread = new Thread(){ public void run() { try { Method getPackageSizeInfo = pm.getClass().getMethod( "getPackageSizeInfo", String.class, IPackageStatsObserver.class); for (AppInfoItem item : installedApp) { sleep(1); // interrupt后会抛异常,这样就可以提前结束线程 getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver); } for (AppInfoItem item : systemApp) { sleep(1); getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); return; } };};readCacheThread.start();在需要中断线程的地方调用:if(readCacheThread != null && readCacheThread.isAlive()){ readCacheThread.interrupt();}
refer:
https://blog.csdn.net/mad1989/article/details/22492519
https://blog.csdn.net/lyf_007217/article/details/8542133
发表评论
最新留言
关于作者
