android service教程

来源:互联网 发布:网络虚拟化技术 编辑:程序博客网 时间:2024/04/29 16:33

原文地址:http://www.javacodegeeks.com/2014/01/android-service-tutorial.html​

在这篇博文中,我们想讨论Android Service。在开发Android app时这是一个重要的组件。跟Activity不同的是,Android中的Service运行在后台,它们没有接口和不同于Activity的生命周期。使用Service我们能实现一些后台操作,例如,我们能支持我们想从一个远程服务器载入一个web页面。在Android中使用Service我们能实现多任务。


Service综述


我们已经知道,如果系统资源变的太低,Android Activity能被开始,停止,销毁和重建,一个Service被设计成有一个更长的生命周期。Android中的一个Service能从一个Activity开始,从一个Broadcast接收,还可以从其它service开始。


我们必须注意到使用Service我们不是自动的创建一个新的线程,因此如果我们在service里实现一个不需要太长时间处理的简单的逻辑,我们不需要在分开的线程中运行它,但是如果我们必须实现使用长时间的复杂的逻辑,我们必须考虑创建一个新线程,否则这个service运行在主线程有可能会导致ANR问题。


在Android中有两个原因适用Service:

实现多任务

开启内部处理通信


第一个案例的一个典型的例子是一个app从一个远程服务器下载输入,在这个案例中我们使Activity跟一个用户交互并且当用户适用这个app的时候开启一个service在后台完成工作,也许当service完成的时候会给用户发送一个消息。


在第二个案例中,我们想“共享”一些共有的方法以至于不同的app能重复利用它们。例如,我们能支持我们是service发送一个邮件并且我们想在几个app之间不需要重写代码就可以共享这个service。在这个案例中我们能使用IPC为的是service暴露一个“远程”接口能被其它app调用。


在这篇文章中,我们包含了第一个例子,在这个例子中我们有一个本地service,本地意味着这个service仅仅能在我们的apk中可见。


Service基础


现在关于Service我们知道了更多,我们想创建它。在Android中,我们想要创建一个Service就必须继承Service类。


public class TestService extends Service {    @Override    public IBinder onBind(Intent arg0) {                return null;    }}


正如我们看到的,我们必须实现叫做onBind的唯一的一个方法。在我们的例子中,我们使用本地service,因此这个方法应该返回null。在我们提及以前,一个Service有它的生命周期并且我们能覆盖一些回调方法来持有它的不同状态。


public class TestService extends Service {    @Override    public void onCreate() {                super.onCreate();    }    @Override    public void onDestroy() {                super.onDestroy();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {                return super.onStartCommand(intent, flags, startId);    }    @Override    public IBinder onBind(Intent arg0) {                return null;    }}


当Service已经被创建的时候,第一个方法onCreate被调用仅仅一次。如果这个Service已经在运行这个方法,那它就不会被调用。我们不会直接调用它,但是它是OS调用的。


onStartCommand是最重要的方法因为当我们请求启动Service时它被调用。在这个方法中我们让Intent传递我们运行的Service,用这种方式,我们能用Service改变一些信息。在这个方法中,我们实现了在这个方法中能直接执行的我们的逻辑,如果它的时间不是昂贵的,否则我们能创建一个线程。正如你看到的这个方法要求我们返回一个整型结果。这个整数代表着这个Service应当被OS如何持有:


START_STICKY:使用返回值,如果OS杀掉我们的Service,它将重新创建它,但是被发送到Service中的Intent不是可传递的。用这种方式Service总是在运行中。

START_NOT_STICKY:如果OS杀掉Service,它将不重新创建它,直到客户端显示调用onStart命令

START_REDELIVER_INTENT:它与START_STICKY是相似的,并且在这个例子中,Intent将被重新传递到Service中。


当Service被销毁的时候,OnDestroy是被OS调用的方法。


一旦我们有了我们的Service类,为了我们能用它,我们必须在Manifest.xml中定义它。

<service android:name=".TestService"          android:enabled="true"/>


开始和停止Service


正如我们了解的,一个Service为了完成它的任务,必须被启动并且完全的被停止。我们能猜想它从一个activity开始,并且我们使用Intent能给service传递一些信息。我们假设我们的Activity有两个按钮,一个是开始,一个是停止Service:

btnStart.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        Intent i = new Intent(MainActivity.this, TestService.class);        i.putExtra("name", "SurvivingwithAndroid");                MainActivity.this.startService(i);            }});btnStop.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        Intent i = new Intent(MainActivity.this, TestService.class);        MainActivity.this.stopService(i);    }});


在上面的第5行,我们创建了一个持有我们的Service的Intent传递类名,而且我们设置一些参数像名字,然后我们在第7行开启Service。用相同的方式,在17行我们停止service。

在start按钮上点击我们得到下面的日志:



因为我们是第一次开启service,因此我们注意到onCreate方法被调用,如果我们再在start按钮上点击,OS不会调用onCreate方法。当我们在stop按钮上点击时,OS销毁service。


IntentService


正如我们提到的,在主线程上,一个service运行以前,我们在这个service中当我们实现一些逻辑时我们必须小心。我们必须考虑是否这个逻辑是一个阻塞操作或者它要求很长时间去完成导致可能出现一个ANR问题。在这个案例中我们必须把我们的逻辑移到分隔的线程中,意味着我们必须在onStartCommand方法中创建一个线程并且运行它。


有另一个由Service衍生而来的叫做IntentService的类简化了我们的工作。当我们在同一时间不需要持有多个请求时这个类是有用的。这个类创建一个工作线程来持有不同的请求。这个类执行这些操作:


创建一个分隔线程持有这个请求

创建一个请求队列并且同时传递一个Intent

创建一个默认的onStartCommand实现

当所有的请求被处理了,停止service


如果我们想创建一个IntentService我们必须继承IntentService类代替Service:

public class TestIntentService extends IntentService {    public TestIntentService() {        super("TestIntentService");            }    @Override    protected void onHandleIntent(Intent intent) {    }}


在这个案例中我们仅仅实现一个叫做onHandleIntent的方法。在这里我们实现输出逻辑,不关心操作是否需要很长时间,因为这个方法在另一个线程中被调用。


自动开启service


很多时候我们想让service自动启动,例如在引导时。我们知道开启一个service我们需要一个开启它的组件。我们该怎么做呢?我们可以使用一个Broadcast接收器开启我们的service。如果按照例子我们想在手机启动时开启它,我们首先要创建一个Broadcast接收器坚挺事件并且然后开启service。

public class BootBroadcast extends BroadcastReceiver {    @Override    public void onReceive(Context ctx, Intent intent) {                ctx.startService(new Intent(ctx, TestService.class));    }}


并且在Manifest.xml中:

<receiver android:name=".BootBroadcast">        <intent-filter >        <action android:name="android.intent.action.BOOT_COMPLETED"/>                    </intent-filter></receiver>


0 0
原创粉丝点击