zoukankan      html  css  js  c++  java
  • android AsynTask 实现原理

    android AsynTask 实现原理

    android asynTask 是借助thread和handler一起结合起来实现的。从其他的Thread操作UI thread 中的view要借组Handler,asynTask封装了这部分的实现,通过ThreadPool实现,doInBackground()方法是在其他的线程中

    运行, onPreExecute()、onProgressUpdate(...)和onPostExecute(...)都是运行的UI主线程中,onPreExecute()和其他两个方法还是有点区别的,它是直接在UI thread 里面运行的,而其他的两个方法是AsynTask里面的IntentHandler里面运行的,从其他的线程里面通过Message将信息传回到主线程中。


    从外部启动调用AsyncTask, 通过调用execute方法。

    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
            return executeOnExecutor(sDefaultExecutor, params);
    }

    用指定的参数执行方法, 放回自身对象,以便调用者可以保持对它的引用。

    注意:这个方法在任务队列上为一个后台线程或者线程池调度任务。默认情况是在单线程中完成任务的。


    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params) {
            if (mStatus != Status.PENDING) {
                switch (mStatus) {
                    case RUNNING:
                        throw new IllegalStateException("Cannot execute task:"
                                + " the task is already running.");
                    case FINISHED:
                        throw new IllegalStateException("Cannot execute task:"
                                + " the task has already been executed "
                                + "(a task can be executed only once)");
                }
            }
    
            mStatus = Status.RUNNING;
    
            onPreExecute();
    
            mWorker.mParams = params;
            exec.execute(mFuture);
    
            return this;
        }
    这个方法必须是在主线程(UI thread)中运行.

    这个方法可以用自定义的Executor,达到多个线程同时执行。

      1. 方法首先是判断当前任务的状态;

      2. 然后执行

            onPreExecute()方法, 这个方法是空的, 如果用户重写了该方法,那么一般是些初始化的操作。   3. 然后把params参数传递给Callback类(Class:WorkerRunnable)的成           员变量mParams;这个参数会用到

    FuthurTask中。

      4.exec默认的情况下其实是SerialExecutor

      5.返回自己


    private static class SerialExecutor implements Executor {
            final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
            Runnable mActive;
    
            public synchronized void execute(final Runnable r) {
                mTasks.offer(new Runnable() {
                    public void run() {
                        try {
                            r.run();
                        } finally {
                            scheduleNext();
                        }
                    }
                });
                if (mActive == null) {
                    scheduleNext();
                }
            }
    
            protected synchronized void scheduleNext() {
                if ((mActive = mTasks.poll()) != null) {
                    THREAD_POOL_EXECUTOR.execute(mActive);
                }
            }
        }
     public AsyncTask() {
            mWorker = new WorkerRunnable<Params, Result>() {
                public Result call() throws Exception {
                    mTaskInvoked.set(true);
    
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    return postResult(doInBackground(mParams));
                }
            };
    
            mFuture = new FutureTask<Result>(mWorker) {
                @Override
                protected void done() {
                    try {
                        postResultIfNotInvoked(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) {
                        postResultIfNotInvoked(null);
                    }
                }
            };
        }

    exec.execute(mFuture);方法调用的时候,SerialExecutor.execute(Runnable r)会被调用,然后

    Executor THREAD_POOL_EXECUTOR=new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

    THREAD_POOL_EXECUTOR调用execute(Runnable r), 下面这段代码会触发执行:

    new Runnable() {
                    public void run() {
                        try {
                            r.run();
                        } finally {
                            scheduleNext();
                        }
                    }
                }

    r.run(); 先调用mWorker.call()方法,在mWorker.call()方法中会触发doInBackground(mParams)方法,然后调用mFuture.done()方法。通过Handler(IntentHandler),

        private static class InternalHandler extends Handler {
            @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
            @Override
            public void handleMessage(Message msg) {
                AsyncTaskResult result = (AsyncTaskResult) msg.obj;
                switch (msg.what) {
                    case MESSAGE_POST_RESULT:
                        // There is only one result
                        result.mTask.finish(result.mData[0]);
                        break;
                    case MESSAGE_POST_PROGRESS:
                        result.mTask.onProgressUpdate(result.mData);
                        break;
                }
            }
        }
    整个调用过程就结束。

    在doInBackground()方法中,如果主动调用了publishProgress(..) ,那么AsyncTask会通过IntentHandler调用onProgressUpdate()方法。








        

  • 相关阅读:
    JS 实现日期信息增加年数,月数,天数
    ROW_NUMBER() OVER函数的基本用法,也可用于去除重复行
    Oracle存储过程返回游标实例详解
    PL/Sql 中创建、调试、调用存储过程
    HTTP 错误 404.13
    oracle查询多行数据合并成一行数据
    C# 实现list=list.OrderBy(q=>q.字段名).ToList(); 按多个字段排序
    [bcc32 Error] ws2def.h(231): E2238 Multiple declaration for 'sockaddr'
    [bcc32 Error] typeinfo.h(154): E2367 Can't inherit RTTI class from non-RTTI base 'exception'
    sql server 语法 MSDN
  • 原文地址:https://www.cnblogs.com/java20130722/p/3207269.html
Copyright © 2011-2022 走看看