Recently inadvertently saw an AsyncTask analysis of an article Asynctask source analysis, I remember very early also read the Guo Shen blog inside Analysis AsyncTask源码 . To see AsyncTask the source code will find that FutureTask it is used in its own constructor, mine sdk is android-23 inside the view.
/** * Creates a new asynchronous task. This constructor must is invoked on the UI thread. */ Public Asynctask() {//Note here that it implements the callableMworker =NewWorkerrunnable<params, result> () { PublicResultPager()throwsException {Mtaskinvoked.set (true); Process.setthreadpriority (Process.thread_priority_background);//noinspection UncheckedResult result = Doinbackground (mparams); Binder.flushpendingcommands ();returnPostresult (result); } };//The futuretask is used hereMfuture =NewFuturetask<result> (Mworker) {@Override protected void Done() {Try{postresultifnotinvoked (get ()); }Catch(Interruptedexception e) {ANDROID.UTIL.LOG.W (Log_tag, E); }Catch(Executionexception e) {Throw NewRuntimeException ("An error occurred while executing doinbackground ()", E.getcause ()); }Catch(Cancellationexception e) {postresultifnotinvoked (NULL); } } }; }
Actually here Callable and FutureTask 2 more important to understand, you can know AsyncTask how to achieve the general. Go to the source to see that they are all Java provided to implement Java concurrency programming.
First look at Callable the code:
public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ throws Exception;}
From code annotations It is clear that returning a result means that we can take some time-consuming actions in it (such as network communication or database operations, etc.) and then return the results after the calculation is done.
Private Static Abstract class workerrunnable<Params, Result> implements Callable<Result> {Params[] Mparams; }//Here in call inside DoinbackgroundMworker =NewWorkerrunnable<params, result> () { PublicResult Call () throwsException{Mtaskinvoked.set (true); Process.setthreadpriority (Process.thread_priority_background);//noinspection UncheckedResult result = Doinbackground (mparams); Binder.flushpendingcommands ();returnPostresult (result); } };
Can see WorkerRunnable is also implemented Callable , and then inside called out doInBackground .
Then we'll look at the FutureTask code:
publicclass FutureTask<V> implements RunnableFuture<V>
publicinterface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run();}
Public interface Future<v> {/** * attempts toCancel execution ofThis task. This attempt would * failif theTask has already completed, have already been cancelled, *orCould notBe cancelled for someOther reason. If successful, * andThis task has notStarted when {@code Cancel} isCalled, * this task should neverRun. If theTask has already started, * Then the{@code mayinterruptifrunning} parameter determines * whether theThread executing this task should be interruptedinch* An attempt toStop theTask. * * <p>after This method returns, subsequent calls to{@link#isDone} would* Alwaysreturn{@codetrue}. Subsequent calls to{@link#isCancelled}* Alwaysreturn{@codetrue}ifThis method returned {@codetrue}. * * @param mayinterruptifrunning {@codetrue}if theThread executing this * task should is interrupted; otherwiseinch-progress Tasks is allowed * toComplete * @return{@codefalse}if theTask could notBe cancelled, * typically becauseithas already completed normally; * {@codetrue} otherwise */BooleanCancelBooleanmayinterruptifrunning); /** * Returns {@codetrue}ifThis task is cancelledbefore itCompleted * normally. * * @return{@codetrue}ifThis task is cancelledbefore itCompleted * *BooleanIsCancelled (); /** * Returns {@codetrue}ifThis task completed. * * Completion may due toNormal termination, an exception,or* Cancellation--In all of these cases, this method would return* {@codetrue}. * * @return{@codetrue}ifThis task completed */BooleanIsDone (); /** * WaitsifNecessary for theComputation toComplete and Then* Retrieves its result. * * @return theComputedresult* @throws cancellationexceptionif theComputation was cancelled * @throws executionexceptionif theComputation threw an * exception * @throws interruptedexceptionif theCurrent thread is interrupted * whileWaiting */VGet() throws Interruptedexception, executionexception; /** * WaitsifNecessary for atMost the given Time for theComputation * toComplete and ThenRetrieves its result,ifAvailable. * * @paramTimeout theMaximum Time toWait * @param unit the TimeUnit of the TimeoutArgument * @return theComputedresult* @throws cancellationexceptionif theComputation was cancelled * @throws executionexceptionif theComputation threw an * exception * @throws interruptedexceptionif theCurrent thread is interrupted * whileWaiting * @throws timeoutexceptionif theWait timed out */VGet(LongTimeout, Timeunit unit) throws Interruptedexception, Executionexception, TimeoutException;}
The code is not much, it is relatively simple.
For a deep understanding of its specific use, we write simple (insane) code.
Private Static classRealdata implements callable<string> {@Override PublicStringPager() throws Exception {//Here is the real business logic that takes a long timeStringBuffer StringBuffer =NewStringBuffer (); for(inti =0; I <Ten; i++) {stringbuffer.append (i);//Simulate a time-consuming operationSystemclock.sleep (1* +); }returnStringbuffer.tostring (); } }Private void testcallable() {futuretask<string> Futuretask =NewFuturetask<string> (NewRealdata ()) {@Overrideprotected void Done() {//futuretask Execution of callbacks completed Try{///Futuretask get () is a synchronous method that will have time to wait, preferably avoid executing in the main threadString str =Get(); System. out. println (); }Catch(Interruptedexception e) {E.printstacktrace (); }Catch(Executionexception e) {E.printstacktrace (); } dosomething (); } };//Custom Executorservice, I will summarize in the following article. Executorservice executor = Executors.newfixedthreadpool (1);//Execute Realdata's call content hereExecutor.submit (Futuretask); System. out. println (); }Private void dosomething() {System. out. println ();/ * Execute callback result * /}
Okay, the simple sample code is written, the call process takes time and results are returned, and then the done get UI can be updated with the notification main thread by getting the results Handler . Remember AsyncTask the code inside the constructor:
Public Asynctask() {Mworker =NewWorkerrunnable<params, result> () { PublicResultPager()throwsException {Mtaskinvoked.set (true); Process.setthreadpriority (Process.thread_priority_background);//noinspection UncheckedResult result = Doinbackground (mparams); Binder.flushpendingcommands ();returnPostresult (result); } }; Mfuture =NewFuturetask<result> (Mworker) {@Override protected void Done() {Try{postresultifnotinvoked (get ()); }Catch(Interruptedexception e) {ANDROID.UTIL.LOG.W (Log_tag, E); }Catch(Executionexception e) {Throw NewRuntimeException ("An error occurred while executing doinbackground ()", E.getcause ()); }Catch(Cancellationexception e) {postresultifnotinvoked (NULL); } } }; }Private void postresultifnotinvoked(Result result) {Final Booleanwastaskinvoked = Mtaskinvoked.get ();if(!wastaskinvoked) {Postresult (result); } }PrivateResultPostresult(Result result) {@SuppressWarnings("Unchecked") Message message = GetHandler (). Obtainmessage (Message_post_result,NewAsynctaskresult<result> ( This, result)); Message.sendtotarget ();returnResult }
It also done uses the Handler send Message to update the UI. All right, simple drip record, let's do it today!!!
Java inside the Futuretask simple use (with source explanation)