Handler消息机制与AsyncTask深度解析-从源码带你看handler

handler在我们Android开发过程中是最长用到的处理消息及其他事务的,其消息机制相信也被大家所熟知 .接下来深入带大家看一下handler的消息机制和AsyncTask的解析


Handler消息机制

  • Hanlder有四大核心类
    • Message
    • Hanldre
    • Messagqueue
    • Looper



Message的实例

Message msg = new Message(); Message.obtain();//取队列的下一个消息 public static Message obtain() { synchronized (mPoolSync) { if (mPool != null) { Message m = mPool; mPool = m.next; m.next = null; return m; } } return new Message(); }

Hanldre的实例

 实例化Hanlder public Handler() { .... //得到一个Looper的实例 mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } //得到消息队列 mQueue = mLooper.mQueue; mCallback = null; } public static final Looper myLooper() { return (Looper)sThreadLocal.get(); } public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper());//实例化Looper } 

Messagqueue的实例,当Looper被创建的时候,同时也创建一个对应的消息队列

private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); } 

Looper的实例,当prepare方法被调用的时候,Looper被实例化

public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper());//实例化Looper }

public static final void prepareMainLooper() { prepare();//调用了prepare方法,其实就是实例化Looper setMainLooper(myLooper()); if (Process.supportsProcesses()) { myLooper().mQueue.mQuitAllowed = false; } } 

谁调用prepareMainLooper方法();当Activity被创建的时候,创建一个对应的线程ActivityThread.java

public static final void main(String[] args) { SamplingProfilerIntegration.start(); Process.setArgV0("<pre-initialized>"); //调用prepareMainLooper Looper.prepareMainLooper(); if (sMainThreadHandler == null) { sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach(false); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop();//轮询器开始工作 } 

Looper.loop()方法的工作原理,代码如下:?

 public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            //if (!me.mRun) {
            //    break;
            //}
            if (msg != null) {
                if (msg.target == null) {
                    // No target is a magic identifier for the quit message.
                    return;
                }
                if (me.mLogging!= null) me.mLogging.println(
                        ">>>>> Dispatching to " + msg.target + " "
                        + msg.callback + ": " + msg.what
                        );
                msg.target.dispatchMessage(msg);
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<< Finished to    " + msg.target + " "
                        + msg.callback);
                msg.recycle();
            }
        }
    }



AsyncTask原理

1.伪代码

 new AsyncTask<String ,String ,String>(){

       //2.在主线程执行,做一条准备操作;
        public void onPreExecute(){

        }
        //3.运行在子线程中,做一些耗时的操作,比如联网请求数据。
        public String doInBackground(String ...params){

            return null;

        }
        //4.result就是doInBackground方法返回的值,做一些释放资源的操作。
        public void onPostExecute(String result){

        }


     }.execute(String ...params);//1.在主线程中执行这个方法,要开始执行异步任务了;

2.模仿AsyncTask的原理,自定义类似于AsyncTask工具类

3.查看AsyncTask源码execute 和构造方法

在AsyncTask中onPreExecute方法代码的实现

 protected void onPreExecute() {
 }


 protected abstract Result doInBackground(Params... params);


 protected void onPostExecute(Result result) {
 }

查看AsyncTask的构造方法

  public AsyncTask() {
    //WorkerRunnable继承或者实现什么 实现Callable接口
    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            return doInBackground(mParams);
        }
    };

    //FutureTask继承或者实现什么 实现RunnableFuture接口 ;
    //RunnableFuture继承两个接口 Runnable, Future
    mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            Message message;
            Result result = null;

            try {
                result = get();
            } catch (InterruptedException e) {
                android.util.Log.w(LOG_TAG, e);
            } catch (ExecutionException e) {
                throw new RuntimeException("An error occured while executing doInBackground()",
                        e.getCause());
            } catch (CancellationException e) {
                message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
                        new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
                message.sendToTarget();
                return;
            } catch (Throwable t) {
                throw new RuntimeException("An error occured while executing "
                        + "doInBackground()", t);
            }

            message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                    new AsyncTaskResult<Result>(AsyncTask.this, result));
            message.sendToTarget();
        }
    };
}

 //callable 是WorkerRunnable
 public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    sync = new Sync(callable);
 }

     //callable 是WorkerRunnable
    Sync(Callable<V> callable) {
        this.callable = callable;
    }

execute()方法的执行,重点,在主线程中执行

public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    ....

    onPreExecute();//主线程

    mWorker.mParams = params;
    sExecutor是什么 线程池ThreadPoolExecutor
    sExecutor.execute(mFuture);mFuture是FutureTask//当这个代码执行的时候会执行 FutureTask的run

    return this;
}

private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXIMUM_POOLSIZE, KEEPALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

FutureTask的run方法代码如下

//1.调用innerRun
public void run() {
    sync.innerRun();
}

 void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;

        runner = Thread.currentThread();
        if (getState() == RUNNING) { // recheck after setting thread
            V result;
            try {
                //2.调用了call方法;callable是WorkerRunnable
                result = callable.call();
            } catch (Throwable ex) {
                setException(ex);
                return;
            }
            //4.设置值
            set(result);
        } else {
            releaseShared(0); // cancel
        }
    }

   mWorker = new WorkerRunnable<Params, Result>() {
          //3.调用call
        public Result call() throws Exception {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            return doInBackground(mParams);//在子线程
        }
    };

 protected void set(V v) {
   //5.
    sync.innerSet(v);
}

  void innerSet(V v) {
        for (;;) {
            int s = getState();
            if (s == RAN)
                return;
            if (s == CANCELLED) {
                // aggressively release to set runner to null,
                // in case we are racing with a cancel request
                // that will try to interrupt runner
                releaseShared(0);
                return;
            }
            if (compareAndSetState(s, RAN)) {
                result = v;
                releaseShared(0);
                //6.
                done();
                return;
            }
        }
    }


 mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            Message message;
            Result result = null;

            try {
                 //7.
                result = get();
            } catch (InterruptedException e) {
                android.util.Log.w(LOG_TAG, e);
            } catch (ExecutionException e) {
                throw new RuntimeException("An error occured while executing doInBackground()",
                        e.getCause());
            } catch (CancellationException e) {
                message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
                        new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
                message.sendToTarget();
                return;
            } catch (Throwable t) {
                throw new RuntimeException("An error occured while executing "
                        + "doInBackground()", t);
            }
            //8.发消息
            //sHandler 是InternalHandler
            message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                    new AsyncTaskResult<Result>(AsyncTask.this, result));AsyncTaskResult 是什么呢
            message.sendToTarget();
        }
    };

private static class AsyncTaskResult<Data> {
    final AsyncTask mTask;
    final Data[] mData;

    AsyncTaskResult(AsyncTask task, Data... data) {
        mTask = task;
        mData = data;
    }
}


 private static class InternalHandler extends Handler {
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
         //9.
        AsyncTaskResult result = (AsyncTaskResult) msg.obj;//取出obj
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                // There is only one result
                //mTask 是AsyncTask
               //10.
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
            case MESSAGE_POST_CANCEL:
                result.mTask.onCancelled();
                break;
        }
    }
}


 private void finish(Result result) {
    if (isCancelled()) result = null;
    //10.
    onPostExecute(result);
    mStatus = Status.FINISHED;
}

转载于:https://my.oschina.net/wszqok/blog/843014

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值