每天进步一点,许多年后再回首就会发现现在的成就,是以前点滴努力的串联。
1.什么是service:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding <service>
declaration in its package's AndroidManifest.xml
. Services can be started withContext.startService()
and Context.bindService()
.
service是一个应用程序组件,用来执行一个长时间运行的操作而不是与用户交互或提供其他应用程序使用的功能。每个service服务必须在AndroidManifest.xml
文件中注册
<service>
。可以使用Context.startService()
和
Context.bindService()方法启动一个sevice。
注意:service不是一个单独的进程,也不是一个线程。即service域ui共享一个线程,如果在service中执行耗时操作会导致主线程阻塞。
2.什么是intentservice:
IntentService is a base class for Service
s that handle asynchronous requests (expressed as Intent
s) on demand. Clients send requests through startService(Intent)
calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
intentservice是一个service的子类,提供异步请求处理intent。可以使用startService(Intent)启动它;当intentservice启动后,会使用一个work线程异步处理intent,每次只能处理一个intent。
3.效果演示:
创建service
public class ServiceTest extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("=========service========="+Thread.currentThread().getId());
try {
//线程休眠10分钟
Thread.sleep(100000);
} catch (Exception e) {
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
}
创建intentservice
public class IntentServiceTest extends IntentService {
public IntentServiceTest(String name) {
super("test");
}
@Override
protected void onHandleIntent(Intent intent) {
System.out.println("=========intentservice========="+Thread.currentThread().getId());
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建两个按钮分别启动service和intentservice
public class MainActivity extends Activity {
private Button startservice=null;
private Button startintentservice=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//打印当前线程id
System.out.println("=========ui主线程========="+Thread.currentThread().getId());
//实例化组件
startservice=(Button) findViewById(R.id.startservice);
startintentservice=(Button) findViewById(R.id.startintentservice);
//绑定监听事件
startservice.setOnClickListener(new MyOnclickListener());
startintentservice.setOnClickListener(new MyOnclickListener());
}
private class MyOnclickListener implements OnClickListener{
public void onClick(View v) {
if(v==startservice){
Intent service=new Intent();
service.setClass(MainActivity.this, ServiceTest.class);
startService(service);
}else if(v==startintentservice){
Intent service=new Intent();
service.setClass(MainActivity.this, IntentServiceTest.class);
startService(service);
}
}
}
首先启动service:线程被阻塞如图1:后台打印内容
11-19 01:53:08.300: INFO/System.out(226): =========ui主线程=========1
11-19 01:53:12.238: INFO/System.out(226): =========service=========1
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
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);
}
}
public IntentService(String name) {
super();
mName = name;
}
/**
* Control redelivery of intents. If called with true,
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_REDELIVER_INTENT} instead of
* {@link Service#START_NOT_STICKY}, so that if this service's process
* is called while it is executing the Intent in
* {@link #onHandleIntent(Intent)}, then when later restarted the same Intent
* will be re-delivered to it, to retry its execution.
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Invoked on the Handler thread with the {@link Intent} that is passed to {@link #onStart}.
* Note that this will be invoked from a different thread than the one that handles the
* {@link #onStart} call.
*/
protected abstract void onHandleIntent(Intent intent);
}