Android之子线程更新UI
16lz
2021-01-23
一、简介
- Android 的UI都是由主线程绘制的
- 和其他大多数GUI库一样,Android 的UI也是线程不安全的,要想更新UI元素,一般必须在主线程中进行,否则会出现异常。
- Android的对此一般采用异步消息处理机制。
- AsyncTask使用线程池,所以比handler效率更高
二、异步消息处理机制
//handler private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) {// super.handleMessage(msg); String str = (String) msg.obj; tv_status.setText(str); //判断当前函数是否在主线程中执行 boolean result = Looper.getMainLooper() == Looper.myLooper(); Log.d(TAG, "handleMessage: "+result); } }; class myThread extends Thread{ @Override public void run() {// super.run(); try { Thread.sleep(1000*6); String str = "子线程消息"; Message message = new Message(); message.obj = str; handler.sendMessage(message); } catch (InterruptedException e) { e.printStackTrace(); } } }
- Message
可以携带少量信息,在线程之间传递,可以使用what、arg1、arg2、obj等字段携带数据。 - Handler
处理者,用于发送和处理消息。sendMessage()方法发送消息,handleMessage()接收。 - MessageQueue
消息队列,存放handler发送的消息,每个线程只有一个MessageQueue对象。 - Looper
MessageQueue的管理者,Looper调用loop()方法,进入无限循环,一发现MessageQueue中有消息,就取出传递给handleMessage(),同样每个线程只有一个Looper对象。
三、AsyncTask
- 使用在代码中做了详细的说明
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private TextView tv_text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_text = (TextView) findViewById(R.id.tv_text); //启动任务 new DownloadTask().execute(10); } /** * 三个泛型参数: * Params 需要传入后台任务的参数,指定类型 * Progress 后台任务执行时进度,指定进度单位 * Result 执行结果,指定返回类型 */ class DownloadTask extends AsyncTask { /** * 后台任务执行前调用,一般用于初始化操作,比如显示一个进度条对话框 */ @Override protected void onPreExecute() {// super.onPreExecute(); tv_text.setText("准备显示"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法中的所有代码都在子线程中运行,处理耗时操作,并返回执行结果 */ @Override protected Boolean doInBackground(Integer... voids) { for (int i = 0; i < voids[0]; i++){ try { Thread.sleep(1000); //传递进度 publishProgress(i); } catch (InterruptedException e) { e.printStackTrace(); } } return true; } /** * 使用后台任务传递的参数,在方法中对UI更新 */ @Override protected void onProgressUpdate(Integer... values) {// super.onProgressUpdate(values); //更新显示 tv_text.setText(""+values[0]); } /** * 后台任务执行完之后调用,并接受返回的参数,更新UI,比如提醒任务结束,关闭对话框等 */ @Override protected void onPostExecute(Boolean b) {// super.onPostExecute(b); tv_text.setText(""+b); } }}
注:当当前的Activity退出后,开启的任务仍然会继续执行,所以,需要停止时就得重写活动的销毁方法,在方法中停止
更多相关文章
- Android Studio部署apk到手机后手机显示中文乱码解决方法
- android TextView多行文本(超过3行)使用ellipsize属性无效问题的
- Android 线程操作之线程池
- Android -- ViewRoot,关于子线程刷新UI
- sencha touch 调用android主函数里的方法(可用与phoneGap开发第三