Service的简单使用

原创 2016年05月31日 10:21:39

转载请注明出处: http://blog.csdn.net/a992036795/article/details/51539694

一、先来看如何最简单的创建一个Service
1、新建一个类继承自Service重写其中的几个重要方法

public class SimpleService extends Service{

    private static final String TAG = "SimpleService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: ");
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                stopSelf();
            }
        },2000);
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "onStart: ");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");

    }
}

我在onStartCommand()中简单写了一个延时调用stopSelf()的方法,用来销毁services。以便测试他的onDestory()方法的执行。
记得要在清单文件中添加:

     <service android:name=".SimpleService" />

最后我们在一个Activity中添加代码,使用startService()方法来启动Service

    findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                starService();
            }

 private void starService() {
        Intent intent = new Intent();
 intent.setComponent(new ComponentName(MainActivity.this,SimpleService.class)) ;
        startService(intent);
    }

最后log显示:

 I/SimpleService: onCreate: 
 I/SimpleService: onStartCommand: 
 I/SimpleService: onStart: 

多次点击将显示:

I/SimpleService:onStartCommand: 
I/SimpleService: onStart:
I/SimpleService:onStartCommand: 
I/SimpleService: onStart:
I/SimpleService:onStartCommand: 
I/SimpleService: onStart:
I/SimpleService:onStartCommand: 
I/SimpleService: onStart:
I/SimpleService:onStartCommand: 
I/SimpleService: onStart:

但最终只会执行一次onDestory().
这是我们就知道,多次调用startService()会执行多次onStartCommand()和onStart(),但实际上每个服务只会存在一个实例。

二、IntentService
它继承自Service重写了Service的OnCrate()、onStart()以及onStartCommand()方法,内部有着一个线程、以及与该线程绑定的一个looper和Hanlder()。每当使用startService()启动该Service,该Services就会回调该service的onStart()方法。最终会执行一次 void onHandleIntent(Intent intent)方法,onHandleIntent是个抽象方法需要我们重写。
这里贴出IntentServie的主要方法:

OnCrate() :创建一个线程并启动该线程,说明一下HandlerThread继承自Thread,它在执行之后会地调用Loop.paper()和Loope.loop()使自己处于死循环。
这里除了启动线程,还获得了该线程对应的looper以及handler

 @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);
    }

onStartCommand()、和onStart()方法:
onStartCommand()调用onStart(),最后使用onCreate()中创建的handle来发送一个消息。


    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    /**
     * 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;
    }

Handle:

 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);
        }
    }

最终会执行一个抽象方法,然后结束自己。
该抽象方法:


    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);

所以使用IntentService很简单

public class SimpleIntentService extends IntentService{

    private static final String TAG = "SimpleIntentService";

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public SimpleIntentService(String name) {
        super(name);
    }


    /**
     * 这里执行任务,执行完成只够改Service会自动销毁
     * @param intent
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAG, "onHandleIntent: ");
    }

}

使用startService()来启动该Service。

三、使用bindService启动一个service
示例:

public class SimpleBindService  extends Service {

    private static final String TAG = "SimpleBindService";
   @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return new Binder();
    }
}

在onBinder()方法中需返回一个Binder对象,传给调用程序。
在来看调用端的程序:


    private ServiceConnection conn  =new ServiceConnection() {
        private static final String TAG = "MainActivity";

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // service 为 Service的onBind()方法返回的Ibinder对象。
            Log.i(TAG, "onServiceConnected: MainActivity ");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "onServiceDisconnected: MainActivity ");
        }
    } ;

    private void bindService() {
       Intent intent =new Intent(MainActivity.this,SimpleBindService.class);
        bindService(intent,conn,BIND_AUTO_CREATE);
    }


  @Override
    protected void onDestroy() {

        super.onDestroy();
        unbindService(conn);
    }

使用bindService来启动service。第一绑定会执行Service的onBind()方法,该方法返回个binder会通过ServiceConnnection的onServiceConnected(ComponentName name, IBinder service)方法返回给调用程序。调用程序可使用这个binder对象来与Service通信。

四、启动一个前台的service.
启动将service默认是运行在后台的,因此它的优先级比价低,当启动出现内存不足的情况时,它有可能会被回收掉。如果希望Service可以一直保持运行状态,而不会因为系统内存不足被杀死。可以将service运行在前台。调用它的startForegroud()方法。
示例:

package com.simple.test03;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

/**
 * Created by blueberry on 2016/5/30.
 */
public class SimpleService extends Service{

    private static final String TAG = "SimpleService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: ");
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("title")
                .setContentText("content") ;
        //被点击时触发的Intent
        Intent intent1 = new Intent(this,SecondActivity.class);

        //创建任务栈build
        TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
        stackBuilder.addParentStack(SecondActivity.class);
        stackBuilder.addNextIntent(intent1);

        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(resultPendingIntent);
        NotificationManager mNotifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = builder.build();
        mNotifyMgr.notify(123,notification);
        startForeground(123,notification);
        builder.build();
        return START_STICKY;
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "onStart: ");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//        startService(new Intent(this,SimpleService.class));
        Log.i(TAG, "onDestroy: ");

    }


}

这样Service就运行在了前台。

最后在说明一下TaskStackBuilder 这个类,使用stackBuilder.addParentStack(SecondActivity.class);
和在SecondActivity在Manifest文件中的设置

 <activity android:name=".SecondActivity"
            android:parentActivityName=".MainActivity"
            ></activity>

,会有一种效果就是:
比如我有个应用我启动service之后会出现通知,然后我退出应用。这时点击通知会进入SecondActivity,然后我返回会启动MainActivity页面,而不是直接退出回到桌面。

版权声明:本文为博主原创文章,未经博主允许不得转载。

分布式服务框架的服务调用

对于分布式服务框架服务调用的一些考虑~~~
  • njys1
  • njys1
  • 2017年03月31日 05:42
  • 392

android中Service使用详解

service用于长期在后台处理任务,而不需要对用户可见。 service有2种基本的启动方式: startService():使用这种方式,来进行单一的任务,不需要返回结果给调用者 bindServ...

Service的理解和使用

Android的Service学习,大致分为两类:started服务(包含IntentService),bound服务。...
  • llayjun
  • llayjun
  • 2016年05月17日 17:33
  • 6290

分享通过在java main函数中执行spring的代码

脱离tomcat容器在单独的java application的main函数中初始化spring
  • yaerfeng
  • yaerfeng
  • 2014年03月12日 11:30
  • 24003

Activity的启动模式

Activity的启动模式有4个,分别为standard、singleTop、singleTask、singleInstance。用户可以在AndroidManifest.xml中注册Activity...

IntentFilter的匹配规则

IntentFilter的匹配规则IntentFilter的使用假如我们要隐式启动一个Activity我们需要成功匹配activity中的任意一个intent-filter。如果要成功匹配该inten...

Android Service使用方法--简单音乐播放实例

      Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了。Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行。 ...
  • cjjky
  • cjjky
  • 2011年06月18日 01:17
  • 24679

Android Service使用方法--简单音乐播放实例

Service是服务,Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行。 Android中的服务,它与Activity不同,它是不能与...

使用CXF开发简单的Web Service

使用CXF开发简单的Web Service 博文我们介绍了Web Service的基本概念,了解它的基本概念之后,我们这篇博文介绍一个开源的WebService框架-Apache...

Service之简单使用

生命周期context.startService() ->onCreate()- >onStartCommand()->Service running--调用context.stopService()...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Service的简单使用
举报原因:
原因补充:

(最多只允许输入30个字)