[Android基础]Service
来源:互联网 发布:三星scx3400扫描软件 编辑:程序博客网 时间:2024/06/02 05:57
一、
Service主要有两种用途:
1.执行耗时操作。因为Service是工作在UI线程(即主线程)中的,所以当想在Service中执行耗时操作,应该新建一个线程。
2.用于组件之间的交互。通过将某些功能以Service组件的形式进行封装,然后提供给其他应用组件调用。
二、
Service的生命周期:
Service有两种调用的方式,根据调用方式的不同,有不同的生命周期。
1.启动模式(即startService())
如果Service用于执行长时间运行的操作,则一般采用启动模式。
如果当前指定的Service实例没有被创建,则调用Service的onCreate()来创建一个实例。
否则直接调用Service的onStartCommand()来运行Service。因此Service的onStartCommand()可能会重复调用多次。所以在onStartCommand()中要注意线程同步。
2.绑定模式(即bindService())
如果Service用于提供一种封装的功能供其他组件使用,则一般采用绑定模式。
如果当前指定的Service实例没有被创建,则调用Service的onCreate()来创建一个实例。
实例启动后,将调用onBind()。onBind将返回一个IBinder接口实例,IBinder允许客户端回调Service的方法。在绑定模式下,Android将调用者(如Activity)和Service绑定在一起,当调用者退出时,Service先后调用onUnbind()和onDestroy()退出。注意onBind只一次,不可多次绑定。
三、
启动模式下的Service:
重点就是onStartCommand()了:
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubreturn super.onStartCommand(intent, flags, startId);}
它的返回值可以取:
START_NOT_STICKY
如果Service在它启动后(从onStartCommand()返回后)被kill掉,那么它将不会被重启。适用场景:网上下载数据。
START_REDELIVER_INTENT
如果Service在它启动后(从onStartCommand()返回后)被kill掉,那么它将会被重启(onCreate()方法会执行),onStartCommand()会执行。并且最后传给它的Intent通过onStartCommand()会被重新传给它。这种模式保证了传递给它的Intent一定会被处理完毕。适用场景:关键业务处理。
START_STICKY
如果Service在它启动后(从onStartCommand()返回后)被kill掉,那么它将会被重启(onCreate()方法会执行),onStartCommand()不会执行。但是Intent不被保留,此时Intent的值为null。适用场景:后台播放音乐。
同时注意的是onStartCommand()中的多请求下的线程同步。
在开发Service组件的过程中,经常要涉及线程及线程同步等复杂的问题。这是我们可以使用IntentService(继承Service)。
IntentService:异步处理服务,新开一个线程,当完成所有的任务以后自己关闭。
IntentService有以下特点:
1.创建一个工作队列,它每次将一个Intent传递到onHandleIntent(),解决了同步的问题。
2.当所有请求被处理完成后,将自动停止服务。
3.提供了一个返回null的onBind()方法的默认实现。
4.提供了onStartCommand()方法的默认实现,它将所有的Intent发送到一个工作队列,并进一步发送到onHandleIntent()方法。
继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent()函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。
下面用一个例子展示一下:
package com.example.test;import java.text.SimpleDateFormat;import android.app.IntentService;import android.content.Intent;import android.os.Bundle;import android.util.Log;/* * IntentService注意点: * 1.通过一个无参数的构造方法,并在方法中调用超类中以字符串为参数的构造方法 * 其中字符串被用来作为IntentService的工作线程的名称 * 2.可以覆盖onCreate(),onDestory()等方法,不过必须在方法的最后调用超类 * 的对应方法的实现,否则将抛出意外 */public class TestService extends IntentService {private int span;public TestService() {super("TestService");}@Overrideprotected void onHandleIntent(Intent intent) {Log.v("onHandleIntent", "服务启动时间" + getCurrentTime());Bundle bundle = intent.getBundleExtra("bundle");span = bundle.getInt("waitTime");long endTime = System.currentTimeMillis() + span * 1000;Log.v("onHandleIntent", "服务持续时间" + span);while (System.currentTimeMillis() < endTime) {try {synchronized (this) {wait(endTime - System.currentTimeMillis());}} catch (InterruptedException e) {e.printStackTrace();}}}@Overridepublic void onDestroy() {Log.v("onHandleIntent", "服务摧毁时间" + getCurrentTime());super.onDestroy();}private String getCurrentTime() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date = sdf.format(new java.util.Date());return date;}}
package com.example.test;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);((Button) findViewById(R.id.start)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this,TestService.class);Bundle bundle = new Bundle();double a = Math.random() * 10;a = Math.ceil(a);int randomNum = new Double(a).intValue();bundle.putInt("waitTime", randomNum);intent.putExtra("bundle", bundle);//Toast.makeText(getApplicationContext(), randomNum + "", Toast.LENGTH_SHORT).show();startService(intent);}});((Button) findViewById(R.id.end)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {stopService(new Intent(MainActivity.this,TestService.class));}});}}
快速点击四次start按钮:
四、
绑定模式下的Service:
1.本地绑定
要实现对Service组件功能的调用,Service组件要做以下改造:
a.将Service组件的功能封装到一个接口中
b.实现一个内部类,它继承Bind类(即实现IBinder接口),并实现上面的接口
c.在Service组件的onBind()中,返回b中的内部类对象,供其他组件使用
下面用一个例子展示一下:
package com.example.test2;public interface ICount {public abstract int getCount();}
package com.example.test2;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class CountService extends Service {private int count;private ServiceBinder serviceBinder = new ServiceBinder();@Overridepublic void onCreate() {super.onCreate();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}count++;Log.v("CountService", "Count is" + count);}}}).start();}@Overridepublic IBinder onBind(Intent intent) {return serviceBinder;}public class ServiceBinder extends Binder implements ICount {@Overridepublic int getCount() {return count;}}}
package com.example.test2;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.util.Log;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends Activity implements ServiceConnection {private ICount iCount;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindService(new Intent("com.example.test2.CountService"), this, BIND_AUTO_CREATE);}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {iCount = (ICount) service;Log.v("MainActivity", iCount.getCount() + "");}@Overridepublic void onServiceDisconnected(ComponentName name) {iCount = null;}@Overrideprotected void onDestroy() {unbindService(this);super.onDestroy();}}
<service android:name=".CountService"> <intent-filter > <action android:name="com.example.test2.CountService"/> </intent-filter> </service>
2.远程绑定
- Android基础 : Android Service
- Android基础 : Android Service
- Android基础之Service
- Android (一) Service基础
- Android基础之Service
- 【Android】Service基础学习
- android service基础
- Android基础------Service服务
- Android--Service之基础
- Android--Service之基础
- android Service基础
- Android--Service之基础
- Android基础--Service应用
- Android基础service简介
- [Android基础]Service
- android的service基础
- Android Service基础
- Android Service 基础详解
- C语言库函数的实现
- linux下c/c++实例之十socket服务器实例
- Android屏幕适配
- 以前整理的C++资料(一)
- mars老师[Android开发视频教学].01_18 文件下载 源码
- [Android基础]Service
- hdu5534Partial Tree(长春现场赛H题)
- MyBatis之传入参数
- Linux下安装MySQL5.7
- java的三大框架
- uva 11536——Smallest Sub-Array
- 输入格式控制
- [NOIP 2014]解方程 秦九韶算法+质数取模
- 黑马程序员 Java 基础:IO 流