关闭

Service的简单使用

标签: androidservice
454人阅读 评论(0) 收藏 举报
分类:

转载请注明出处: 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页面,而不是直接退出回到桌面。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:96384次
    • 积分:1947
    • 等级:
    • 排名:千里之外
    • 原创:97篇
    • 转载:1篇
    • 译文:0篇
    • 评论:72条
    博客专栏
    文章分类
    最新评论