天天看点

android-更新UI的几种方式前言

更新UI的几种方式

  • 前言
    • 更新UI的4种方法
      • Handler
      • view.post
      • runOnUiThread
      • AsyncTask

前言

在android中,为了避免在子线程中更新UI造成多线程安全问题(View中更新UI的方法大多不是同步方法),就将UI的更新切换到主线程更新,使用的就是android的Handler机制。在android中可以直接使用Handler进行更新UI,也可以使用Handler的实现进行更新UI,接下来我们盘点下android中更新UI的几种方法,也算是对Handler学习的使用。

更新UI的4种方法

这里介绍更新UI的4种方法,

Handler、view.post、runOnUiThread、AsyncTask

,首先介绍其使用方法,后面在介绍其相关源码。

首先我们知道在android中使用子线程直接更新UI会抛出异常,对于抛出异常的类就是

ViewRootImpl

类的

void checkThread()

方法,这个方法就是判断两个线程是否是一个线程。

mThread

是在

ViewRootImpl

构造方法

中调用

Thread.currentThread()创建

,获取的当前线程主线程。

Thread.currentThread()

的作用就是返回一个

当前正在执行的线程

,这是一个Thread类的native方法。当构造方中的主线程不等于当前运行的线程时,说明是在非主线程更新的UI,将抛出异常。

void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }
           

接下来我们看更新UI的几种写法,虽然有点像孔乙己教茴香豆的茴字怎么写,但这不是重点,重点是后面我们要看的其源码具体是怎么玩的。

public class RefreshViewActivity extends Activity implements View.OnClickListener {
    /**
     * Handler
     */
    private Button mBtHandler;
    /**
     * postView
     */
    private Button mBtPostView;
    /**
     * AsyncTask
     */
    private Button mBtAsyncTask;
    /**
     * runOnUiThread
     */
    private Button mBtRunOnUiThread;

    private EditText mEtData;
    private Handler handler;
    /**
     * 取消AsyncTask
     */
    private Button mBtAsyncTaskClean;
    private ProgressBar mProgressBar;
    private MyTask mTask;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_refresh);
        initView();
        /**
         * 造成Handler内存泄漏两个原因
         *
         * 1、Handler内部类的创建方式导致隐式持有外部Activity的引用,当Handler所伴随的线程无法及时发送消息,但此时又关闭了Activity
         * 那么线程将持有handler,handler由持有Activity,导致内存无法回收造成泄漏
         * 2、当使用postDelayed延迟发送消息,导致Message占用MessageQueue、message、handler,activity一条消息链,导致Activity无法回收
         * 避免内存泄漏 使用静态内部类 或弱引用并在Activity销毁的时候回收Message
         */

        handler = new MyHandler(this);
        /**
         * AsyncTask子类的实例必须在UI线程中创建
         * AsyncTask也会有和Handler相识的内存泄漏问题
         */
        mTask = new MyTask();
    }

    private class MyHandler extends Handler {
        WeakReference<RefreshViewActivity> weakReference;
        Context context;

        public MyHandler(RefreshViewActivity activity) {
            context = activity;
            weakReference = new WeakReference(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (weakReference.get() != null) {
                if (msg.what == 1) {
                    mEtData.setText("handler");
                }
            }
        }
    }

    private void initView() {
        mBtHandler = (Button) findViewById(R.id.bt_handler);
        mBtHandler.setOnClickListener(this);
        mBtPostView = (Button) findViewById(R.id.bt_postView);
        mBtPostView.setOnClickListener(this);
        mBtAsyncTask = (Button) findViewById(R.id.bt_asyncTask);
        mBtAsyncTask.setOnClickListener(this);
        mBtRunOnUiThread = (Button) findViewById(R.id.bt_runOnUiThread);
        mBtRunOnUiThread.setOnClickListener(this);
        mEtData = findViewById(R.id.et_data);

        mBtAsyncTaskClean = (Button) findViewById(R.id.bt_asyncTask_clean);
        mBtAsyncTaskClean.setOnClickListener(this);
        mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_handler:
                onHandler();
                break;
            case R.id.bt_postView:
                onPostView();
                break;
            case R.id.bt_runOnUiThread:
                onRunOnUiThread();
                break;
            case R.id.bt_asyncTask:
                /**
                 * :
                 * 手动调用execute(Params... params) 从而执行异步线程任务
                 * 注:
                 *    a. 必须在UI线程中调用
                 *    b. 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
                 *    c. 执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute() 、doInBackground()、onProgressUpdate() 、onPostExecute()
                 *    d. 不能手动调用上述方法
                 */
                mTask.execute();
                break;
            case R.id.bt_asyncTask_clean:
                /**
                 *  取消一个正在执行的任务,onCancelled方法将会被调用
                 *  先点击取消销毁后,再执行会报错
                 */
                mTask.cancel(true);
                break;
        }
    }


    private void onRunOnUiThread() {

        /**
         * 执行完run()方法Thread就进入到死亡状态,当run()方法存在柱塞的时候,要注意回收线程
         */
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mEtData.setText("runOnUiThread");
                    }
                });
            }
        });
        thread.start();

    }


    private void onPostView() {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                mEtData.post(new Runnable() {
                    @Override
                    public void run() {
                        mEtData.setText("onPostView");
                    }
                });

            }
        });
        thread.start();
    }

    private void onHandler() {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = handler.obtainMessage();
                message.what = 1;
                handler.sendMessage(message);
            }
        });
        thread.start();

    }


    /**
     * 步骤1:创建AsyncTask子类
     * 注:
     * a. 继承AsyncTask类
     * b. 为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
     * 此处指定为:输入参数 = String类型、执行进度 = Integer类型、执行结果 = String类型
     * c. 根据需求,在AsyncTask子类内实现核心方法
     */
    private class MyTask extends AsyncTask<String, Integer, String> {
        /**
         * 方法1:onPreExecute()
         * 作用:执行 线程任务前的操作
         */
        @Override
        protected void onPreExecute() {
            mEtData.setText("加载中");
            // 执行前显示提示
        }


        /**
         * 方法2:doInBackground()
         * 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
         * 此处通过计算从而模拟“加载进度”的情况
         *
         * @param strings
         * @return
         */
        @Override
        protected String doInBackground(String... strings) {
            try {
                int count = 0;
                int length = 1;
                while (count < 99) {

                    count += length;
                    // 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
                    publishProgress(count);
                    // 模拟耗时任务
                    //中途取消的时候会 java.lang.InterruptedException
                    Thread.sleep(50);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 方法3:onProgressUpdate()
         * 作用:在主线程 显示线程任务执行的进度
         *
         * @param progresses
         */
        @Override
        protected void onProgressUpdate(Integer... progresses) {
            mProgressBar.setProgress(progresses[0]);
            mEtData.setText("loading..." + progresses[0] + "%");
        }

        /**
         * 方法4:onPostExecute()
         * 作用:接收线程任务执行结果、将执行结果显示到UI组件
         *
         * @param result
         */
        @Override
        protected void onPostExecute(String result) {
            // 执行完毕后,则更新UI
            mEtData.setText("加载完毕");
        }
        /**
         * 方法5:onCancelled()
         * 作用:将异步任务设置为:取消状态
         */
        @Override
        protected void onCancelled() {
            mEtData.setText("已取消");
            mProgressBar.setProgress(0);
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
    }
}

           

上面的代码很简单XML文件我就不贴出来了,写了4种更新UI的方法,以及Handler关于内存泄漏的原因和解决方法,以及AsyncTask的使用注意事项,AsyncTask部分代码参考于其他博客。接下来我们看看其相关源码。

Handler

对于handler的理解可以看之前写的

android-Handler源码解析

android-重新理解Handler

view.post

根据方法调用方法我基本知道post(Runnable action)方法位于view类,下面的代码意思就是

1、当

attachInfo不为空

的时候,直接调用其

handler的post(Runnable action)

方法

2、当

attachInfo为空

,会调用

getRunQueue().post(action)将其加入到队列

当中,直到后面再调用,HandlerActionQueue可以自行看看,很简单,就是一个数组,将Runnable封装后保存。

1、这里我们要知道AttachInfo什么时候创建

2、加入队列后什么什么时候再调用

3、以及什么时候mRunQueue == null(后面学习View的时候再讲解)

private HandlerActionQueue mRunQueue;
    
	 public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }
...
	 private HandlerActionQueue getRunQueue() {
        if (mRunQueue == null) {
            mRunQueue = new HandlerActionQueue();
        }
        return mRunQueue;
    }
...

           

我看看

attachInfo.mHandler.post(action)

;其实调用的是

handler的post(action)

方法,那么我们回顾下。

当我们直接调用handler的post(Runnable r)方法,就是延迟0秒发送了一个Message,

并将传递的Runnable,赋值给了 m.callback

public class Handler {
...
	 public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

	private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
	
...

}
           

AttachInfo是View的静态内部类,

AttachInfo

handler

就是在其

构造方法中传递过来的

,首先看看AttachInfo是在哪里得到的,在View中找到两处,再看看什么时候调用这两个方法。对于这两个方法,好像很难在AS中直接找到,所以最好是下载源码直接在工具里面找,可以找到在

ViewRootImpl中有相关代码

private HandlerActionQueue mRunQueue;
    
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
        mAttachInfo = info;
        ...
		  if (mRunQueue != null) {
            mRunQueue.executeActions(info.mHandler);
            mRunQueue = null;
        }
        ...
   }     
           
void dispatchDetachedFromWindow() {
		...
		   mAttachInfo = null;
		...
  }
           

ViewRootImpl

类的构造方法中,可以看到

AttachInfo的初始化

,ViewRootImpl是View和Window的纽带,后面在介绍View的相关知识在详细讲解。先看看这次讲解的部分代码

在下面代码中我们可以看到,

1、

AttachInfo的创建是在ViewRootImpl的构造方法中

,在

ViewRootImpl

中有一个

Handler的实现类ViewRootHandler

,其获取的就是MainLooper,也是这类创建的Handler实例并传递到AttachInfo中的。

2、得到

AttachInfo后要进行传递到到View

中,看

ViewRootImpl

performTraversals()方法

,其中有一句

host.dispatchAttachedToWindow(mAttachInfo, 0)

;

host就是一个View

,这样在

dispatchAttachedToWindow()

方法里就得到了AttachInfo。

3、在

attachInfo.mHandler.post(action)

调用后,Looper开始消息循环,最后得到消息,调用handler的dispatchMessage(Message message)方法,

如果msg.callback != null,则直接调用其run()方法,开始更新UI

4、对于

添加到缓存中的Runnable,则是在dispatchAttachedToWindow方法中被调用

,首先对mRunQueue判空,然后执行

mRunQueue.executeActions(info.mHandler)

;请看上面源码。

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks 
        {
        
...
    public ViewRootImpl(Context context, Display display) {
         mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
                context);
	}
	private final static int MSG_INVALIDATE = 1;
...
	final class ViewRootHandler extends Handler {
        @Override
        public String getMessageName(Message message) {
            switch (message.what) {
                case MSG_INVALIDATE:
                    return "MSG_INVALIDATE";
                ...
               
                case MSG_DRAW_FINISHED:
                    return "MSG_DRAW_FINISHED";
            }
            return super.getMessageName(message);
        }

        @Override
        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
            if (msg.what == MSG_REQUEST_KEYBOARD_SHORTCUTS && msg.obj == null) {
                // Debugging for b/27963013
                throw new NullPointerException(
                        "Attempted to call MSG_REQUEST_KEYBOARD_SHORTCUTS with null receiver:");
            }
            return super.sendMessageAtTime(msg, uptimeMillis);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INVALIDATE:
                    ((View) msg.obj).invalidate();
                    break;
              ...
     
                case MSG_DRAW_FINISHED: {
                    pendingDrawFinished();
                } break;
            }
        }
    }
    final ViewRootHandler mHandler = new ViewRootHandler();
...
}
           
public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
           

runOnUiThread

runOnUiThread是Activity类的方法,看了下源码。这就过分了,直接Handler更新,很简单。不过这个Activity类真是绝了,实现了很多接口。我们看看相关代码

源码很简单,判断下是否等于mUiThread,不等于就使用mHandler更新,等于就直接调用action.run(),mUiThread的获取在在attach(…)方法中。

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback,
        AutofillManager.AutofillClient {
...        
	final Handler mHandler = new Handler();
...
    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

...
	final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        ...
          mUiThread = Thread.currentThread();
        ...

	}
...

}

           

AsyncTask

对于AsyncTask其实是一个比较要学习的东西,因为其包含了两个很重要的东西,第一个就是

ThreadPool

,然后就是

Handler

。那这里我们主要介绍的是Handler的相关知识。在后面再学习Thread和ThreadPool的时候再后头介绍AsyncTask。

在上面使用AsyncTask中我们new一个内部类MyTask,并且在 doInBackground()方法中调用publishProgress(count)更新进度,

mTask.execute()开始执行异步操作, mTask.cancel(true)取消任务。

比较关键的是在AsyncTask的构造方法

1、首先获取一个运行在主线程的Handler

2、构造一个

可执行的异步线程FutureTask(mFuture)

,FutureTask这个异步任务

主要是可以取消

,这个在我们

mTask.cancel(true)

就会执行其相关方法。

3、执行 外部执行mTask.execute(),会得到

sDefaultExecutor和参数

sDefaultExecutor是执行SerialExecutor静态内部类

,后

赋值给sDefaultExecutor

的,也就是

最后执行的是SerialExecutor

。在 executeOnExecutor(Executor exec,

Params… params)方法中可以看到,

先调用 onPreExecute()方法

,在真正的执行异步任务

exec.execute(mFuture)

4、再看真正的执行execute的 SerialExecutor类,在

SerialExecutor

中的

execute

方法,传递过来一个

r

,调用了

r.run()

;这里要知道

r

,就是

FutureTask

,这个

r.run()

后就调用

scheduleNext()

开始真正启动了异步任务,mTasks取出一个Runnable将其交给mActive,然后再交由THREAD_POOL_EXECUTOR线程池来执行

5、r.run()执行后,其实要看看FutureTask类中的run方法,下面贴出源码。在

newFutureTask

的时候已经将

WorkerRunnable

传递进去了,

WorkerRunnable其实是一个Callable

,在FutureTask的run()方法里面有看到

result = c.call();

这样其实调用的

WorkerRunnable的call()方法

,这样就执行到了

doInBackground()

方法,在我们实现的doInBackground中调用

publishProgress(count)更新进度UI

,并且执行

postResult(result)

发送消息给Handler

。Handler根据msg.whatk开始执行

result.mTask.finish(result.mData[0])

,也就是

AsyncTask

finish(Result result)

方法。

6、finish(Result result)方法比较简单,

判断是否是取消

,是取消执行

onCancelled(result)

;,不是取消就完成执行回调

onPostExecute(result)

7、执行

mTask.cancel(true)

,首先将

取消置为true,(mCancelled.set(true))

。取消操作大家去看FutureTask源码可以看到,肯定会调用

done()

方法,后头再看

AsyncTask中new的FutureTask,其中done()也会调用postResultIfNotInvoked()

,其中会判断当前异步 任务是否真正开始,如果异步已经

开始则不能取消

,如果

没有开始则发送消息给handler,同样执行result.mTask.finish(result.mData[0])

,这样就

再回到上面6

进行判断。

到这里AsyncTask的基本逻辑就全部走了一遍,主要没有讲解线程池这一块内容,对于AsyncTask的实现方式走了流水其实并不够,后面要学习其设计优雅的地方,这样才是学到了精华。走流水其实只是学习的第一步,还是要消化精华。

public abstract class AsyncTask<Params, Progress, Result> {
	public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
   	 // AsyncTask默认使用SERIAL_EXECUTOR作为它的Executor,所以默认情况下AsyncTask是串行而非并行执行的
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

    // 通过handler发布result的message code 
	private static final int MESSAGE_POST_RESULT = 0x1;
	// 通过handler发布progress的message code
	private static final int MESSAGE_POST_PROGRESS = 0x2;
	
	// 任务是否被取消的标识
	private final AtomicBoolean mCancelled = new AtomicBoolean();
	// 任务是否真正开始了的标识
    private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
...
	 private static Handler getMainHandler() {
        synchronized (AsyncTask.class) {
            if (sHandler == null) {
                sHandler = new InternalHandler(Looper.getMainLooper());
            }
            return sHandler;
        }
    }
...
	public AsyncTask() {
        this((Looper) null);
    }
	 public AsyncTask(@Nullable Handler handler) {
        this(handler != null ? handler.getLooper() : null);
    }

    /**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     *
     * @hide
     */
    public AsyncTask(@Nullable Looper callbackLooper) {
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);

        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                // 将任务开始标识设为true
                mTaskInvoked.set(true);
                Result result = null;
                // 将call方法设置为后台线程级别    
                try {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                 // 在线程池中执行doInBackground()方法,并返回result
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                // 将结果交由postResult()方法
                    postResult(result);
                }
                return result;
            }
        };

        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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
...

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

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

	   private static class SerialExecutor implements Executor {
       // 一个双端队列,用来存放任务Rnnable类
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
         // 当前正在执行的Runnable     
        Runnable mActive;
         我们调用SerialExecutor的execute()会将Runnable再次封装,将其放入到双端队列mTasks的最后面。判断mActive是否为null来判断当前是否有任务在执行,如果没有任务在执行那么从任务队列中去一个任务去执行,如果有任务在执行则等待这个任务执行完毕后在finally中去取下一个任务

        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }
       // mTasks取出一个Runnable将其交给mActive,然后再交由THREAD_POOL_EXECUTOR线程池来执行
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }
...
	public final boolean cancel(boolean mayInterruptIfRunning) {
        mCancelled.set(true);
        return mFuture.cancel(mayInterruptIfRunning);
    }

	 private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }

	private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

	private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

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

...
	 private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

...



}
	
           
public class FutureTask<V> implements RunnableFuture<V> {
...
	   public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
	
	 public void run() {
        if (state != NEW ||
            !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

...

}
           

线程之AsyncTask的完全解析

继续阅读