IntentService和HandlerThread 使用与区别

1:IntentService介绍和IntentService与Server的区别;

2:HandlerThread的介绍;

3:IntenetServer的使用;

 

1:1:IntentService介绍和IntentService与Server的区别;

/**
 * IntentService 介绍
 * IntentService 是一种特殊的 Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能够使用 IntentService。
 * 它可用于执行后台耗时任务,当任务执行完成后它会自动停止,在资源不足时,系统会对一些被认为时无用的资源给清理掉,
 * 由于它是 Service 的原因,它的优先级比单纯的线程的优先级高很多,不容易被系统杀死(清理掉),所以它适合执行一些高优先级的后台任务。
 * 在实现上,IntentService 封装了 Handlerhread 和 Handler。
 * 另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,
 * 并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
 */

/**
 * InteneServer和Server的区别(来源:https://blog.csdn.net/mp624183768/article/details/54882965):
 * 1:Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR,为了解决这样的问题,引入了IntentService;
 * 2:IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期。
 * 那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作
 * IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务。
 * IntentService有以下特点:
 (1)  它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
 (2)  创建了一个工作队列,来逐个发送intent给onHandleIntent()。
 (3)  不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
 (4)  默认实现的onBind()返回null
 (5)  默认实现的onStartCommand()的目的是将intent插入到工作队列中
 */
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);
        }
    }

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public IntentService(String name) {
        super();
        mName = name;//构造时,传入我们创建的IntentServer的名字
        /**
         * IntentServer生命周期
         * 1:onCreate()初始化HandlerThread和ServiceHandler,用于在后面调用onStart后来发送消息
         * 2:每次启动服务都会调用一次onStartCommand()方法,并且它会调用onStart()
         * 3:在onStart()中发送消息
         */
    }

    /**
     * Sets intent redelivery preferences.  Usually called from the constructor
     * with your preferred semantics.
     *
     * 

If enabled is true, * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_REDELIVER_INTENT}, so if this process dies before * {@link #onHandleIntent(Intent)} returns, the process will be restarted * and the intent redelivered. If multiple Intents have been sent, only * the most recent one is guaranteed to be redelivered. * *

If enabled is false (the default), * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent * dies along with it. */ public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @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. //onCreate被执行时内部会开启一个线程和创建一个消息队列,用于解决在后台服务中进行的耗时操作; super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper();//创建队列,获取looper对象 mServiceHandler = new ServiceHandler(mServiceLooper);//创建线程对象 } @Override public void onStart(@Nullable 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(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); /** * {@link mRedelivery }会根据setIntentRedelivery()设置的布尔值返回START_REDELIVER_INTENT or START_NOT_STICKY; * START_NOT_STICKY:服务会直接被关闭,当我们的操作不是十分重要的时候,我们可以选择START_NOT_STICKY,这也是IntentService的默认选项 * START_REDELIVER_INTENT :服务会在可用资源不再吃紧的时候尝试再次启动服务,当我们认为操作十分重要时,则应该选择START_REDELIVER_INTENT 型服务 */ return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } /** * Unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns null. * @see android.app.Service#onBind */ @Override @Nullable public IBinder onBind(Intent intent) { return null; } /** * This method is invoked on the worker thread with a request to process. * Only one Intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. * When all requests have been handled, the IntentService stops itself, * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. * This may be null if the service is being restarted after * its process has gone away; see * {@link android.app.Service#onStartCommand} * for details. */ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }

HandlerThread介绍

/**
 * Handy class for starting a new thread that has a looper. The looper can then be 
 * used to create handler classes. Note that start() must still be called.
 * 它是一种可以使用Handler的Thread,内部对Thread的run()进行重写,它实现是通过在run()方法中通过looper.prepare()来创建消息队列,
 * 并通过Looper.loop()方法来开启消息循环,通过Handler的消息方式(looer循环)来通知HandlerThread执行一个具体的任务;
 */
public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    private @Nullable Handler mHandler;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    
    /**
     * Constructs a HandlerThread.
     * @param name
     * @param priority The priority to run the thread at. The value supplied must be from 
     * {@link android.os.Process} and not from java.lang.Thread.
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }
    
    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
    
    /**
     * This method returns the Looper associated with this thread. If this thread not been started
     * or for any reason isAlive() returns false, this method will return null. If this thread
     * has been started, this method will block until the looper has been initialized.  
     * @return The looper.
     */
    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    /**
     * @return a shared {@link Handler} associated with this thread
     * @hide
     */
    @NonNull
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

    /**
     * Quits the handler thread's looper.
     * 

* Causes the handler thread's looper to terminate without processing any * more messages in the message queue. *

* Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. *

* Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. *

* * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * 使用此方法可能是不安全的,因为在looper队列终止之前可能无法传递某些信息 * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } /** * Quits the handler thread's looper safely. *

* Causes the handler thread's looper to terminate as soon as all remaining messages * in the message queue that are already due to be delivered have been handled. * Pending delayed messages with due times in the future will not be delivered. *

* Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. *

* If the thread has not been started or has finished (that is if * {@link #getLooper} returns null), then false is returned. * Otherwise the looper is asked to quit and true is returned. *

* 使用此方法可能是安全的,因为一旦已经传递消息,队列中的所有剩余消息被处理,方法就会终止,然而, * 在循环终止之前,延迟的消息将在未来到期时间内不传递 * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * Returns the identifier of this thread. See Process.myTid(). */ public int getThreadId() { return mTid; } }

 

IntentService使用:
/**
 * 1:需要在mainfest中注册服务;
 * 2: Intent intent = new Intent(MainActivity.this, IntentServerDemo.class);
        intent.putExtra("action","TASK1"); startService(intent);
 */
public class IntentServerDemo extends IntentService{

    /**
     * Error:has no zero argument constructor
     */
    public IntentServerDemo(){
        super("");
    }
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public IntentServerDemo(String name) {
        super(name);
        Log.i("bugtags",">>>IntentServerDemo=="+name);
    }

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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.i("bugtags",">>>onHandleIntent="+intent.getStringExtra("action"));
        SystemClock.sleep(5000);
    }

    @Override
    public void onDestroy() {
        Log.i("bugtags",">>>onDestroy");
        super.onDestroy();
    }
}

 

 

你可能感兴趣的:(Android)