博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android-non-ui-ui-thread-communications-part-5-5
阅读量:5058 次
发布时间:2019-06-12

本文共 9730 字,大约阅读时间需要 32 分钟。

This is the last post in my series regarding Android thread communications.  Parts 1 through 4 are linked in below.

In this series, I have so far outlined four different approaches for how Android non-user interface threads can communicate user interface (UI) updates back to the UI thread.  As you have learned in this series, new threads to perform longer running work is the way to build applications and to avoid Android Not Responsive popups, but if those non-UI threads try to update UI components (like putting new String data in a TextView widget) they trigger a CalledFromWrongThreadException.  Previous posts have used the Activity’s runOnUiThread() method, a View’s post() method, the Handler Framework, and Broadcast/BroadcastReceiver components to handle non-UI to UI thread communications.  In this last post, my favorite option – the AsyncTask – is explored.

THE SIMPLE APP REVIEW

As reminder or note to those looking at these posts out of sequennce, throughout this series, I have used the same simple application (called Simple App) to demonstrate each communication option.  The Simple App has two buttons to start/stop a non-UI thread.  The non-UI thread’s job is to simulate long running work by generating a random number, then call the UI to have a TextView widget update the display of the random number, and then sleep for a number of seconds.

The SimpleApp example code for demonstrating option #5 can be found (in an Eclipse project ZIP file).

ASYNCTASK

The AsyncTask is a special Android convenience class for creating a new Thread that can “publish results on the UI thread without having to manipulate threads and/or handlers.”  That last quote is directly from the in the Android reference guide.  In other words, the AsyncTask was explicitly built to provide Android developers with an easy way to create threads that have a direct communication channel back to the UI thread.

In order to create an AsynTask, developers must extend the abstract AsyncTask super class and then implement the methods below.

  • doInBackground() – code here is executed on a new, non-UI thread that Android creates when the AsynTask is executed.  This is the only required method of an AsyncTask subclass.
  • onPreExecute() – code executed on the UI thread by Android before non-UI thread work is executed in doInBackground() code.
  • onPostExecute() – code executed on the UI thread by Android after non-UI thread work is executed in doInBackground.
  • onProgressUpdate – called on the UI thread by Android whenever publishProgress(Progress…) is called (typically in the doInBackground method) to provide the user interface (and user) with updates while the separate thread is still running.

Notice that three of four methods of the AsyncTask run on the UI thread.  The only method that runs in a non-UI thread is doInBackground().  So you can see the AsyncTask was really built to provide that non-UI to UI communications.

To exemplify AsyncTask’s capability, I created an inner class for the AsyncTask (called DoSomethingTask) to compute the random number and return the results to the UI.  Here is the code (again – it can be pulled from the Eclipse download referenced above).

Note the random number generation (as well as the thread sleeping) occurs in the doInBackground() method – again to simulate long running, continuous work that is often accomplished in a background thread.  Also note that the doInBackground() method calls postProgress() with new String data after it has generated a random number and wants to send this data back to the UI thread.

DoSomethingTask extends AsyncTask and has three generic types.  The first, which in this example is Void, defines the input parameter type.  This simple task takes no input from the UI to generate a random number.  Your background work may need some information from the UI side to get it working and this parameter specifies the type of information being supplied.  This type defines the input parameter type for the doInBackground() method.

The second AsyncTask generic type provided, which is a String here, is the type of data passed to the onProgressUpdate() method in publishProgess() calls made from doInBackground().  Here, the new random number generated by doInBackground() is passed back to the UI thread in order to update the display by passing the random number as String text to the onProgressUpdate() call.

The last generic type to AsyncTask subclasses is the return type of the doInBackground() work.  In this case, the doInBackground() method does not return anything back to the UI thread (except through onProgressUpdate) so the third type is also Void.  Again, your non-UI threads may wish to return some information back to the thread’s creator and this is the type of information passed back.

With this AsyncTask in place, the UI – namely the owning Activity that drives the application – can create an instance of the AsyncTask (DoSomethingTask) and have its background work begin by calling execute.  This work is accomplished in the startGenerating() method (below) which I have setup to be called by an onClickListener waiting for the Start button to be pushed.

Finally, the AsyncTask calls the Activity’s updateResult() method (below) from the onProgressUpdate() method when a new random number is generated and the UI TextView displaying the number needs to be updated.  Again, this is possible because the onProgressUpdate() method runs on the UI thread.

Note additional cleanup methods are provided in the code to stop the AsyncTask when the Stop button is pushed. It should also be noted that this example was kept simple for demonstration sake.  Therefore, it has some faults you would want to correct in a real app situation.  For example, you might want to make sure only one AsyncTask is ever created (right now you could create many by clicking on Start many times).

CONSIDERATIONS OF OPTION 5 – ASYNCTASK

The AsyncTask is a real convenience for Android developers in that it allows them to accomplish multithreading without having to think about all the communications across threads and without having to think about Runnables, Thread instances, special methods to call, queues, etc. to get the work done.  The convenience of the three UI-thread methods makes getting information across the thread boundry real easy.  However, the AsyncTask is fairly basic and when more complex multithreading needs arise, it may be too simple to use.  In fact, the documentation is pretty clear about when to use AsyncTask and when to move to something like classes available in Java’s concurrent package.

AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.

While in this example, the AsyncTask was built as inner class to the Activity, the AsyncTask can be a completely separate class with no ties to the Activity or other UI component.  This allows the non-UI threads to be completely decoupled from the UI.

WRAP UP

So I hope on your next Android project, you’ll remember that you have lots of options for thread communications when it comes time to move background work to a separate non-UI thread.  Namely, you can:

  • Use runOnUiThread( ) method call
  • Use post( ) method call
  • Use the Handler framework
  • Use a Broadcasts and BroadcastReceiver (optionally with LocalBroadcastManager)
  • Use an AsyncTask’s onProgressUpdate( ) method

Good Android developers know it is important to use separate threads to avoid ANR.  The trick is sometimes figuring out how to get those threads communicating without creating other problems like CalledFromWrongThreadException.  Now you are armed with an understanding of thread communication options and considerations for making the best decision for your application needs.

Allow to help guide you through other mobile development technology issues and considerations.  If you need training in Android, iOS or other mobile development platform, please checkout our .  Or, contact our if you need some help on your mobile project.  We are the home of instructors that consult and consultants that teach.

Read more:  
Follow us:  | 

转载于:https://www.cnblogs.com/GoAhead/p/4186670.html

你可能感兴趣的文章
【蓝桥杯】PREV-21 回文数字
查看>>
html 简介
查看>>
python使用上下文对代码片段进行计时,非装饰器
查看>>
js中比较实用的函数用法
查看>>
安装预览版镜像后无法检测到预览版更新的解决方案
查看>>
【bzoj5099】[POI2018]Pionek 双指针法
查看>>
别让安全问题拖慢了 DevOps!
查看>>
JAR打包和运行
查看>>
session如何保存在专门的StateServer服务器中
查看>>
react展示数据
查看>>
测试计划
查看>>
idea设置自定义图片
查看>>
[高级]Android多线程任务优化1:探讨AsyncTask的缺陷
查看>>
选择器
查看>>
rownum 的使用
查看>>
Mysql与Oracle 的对比
查看>>
MVC系列博客之排球计分(三)模型类的实现
查看>>
Android短信拦截
查看>>
11G RAC ORA-27090: Unable to reserve kernel resources for asynchronous disk I/O
查看>>
11G RAC 修改 SGA PGA
查看>>