Android 异步消息处理机制
本篇讲解android子线程中更新UI的三种方法。
1. Handler
public class TestHandlerFragment extends BaseFragment implements View.OnClickListener { private Button button; private Handler mhandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case ST_HANDLER_LICENSE_GET: button.setText("after change Btn Text"); break; default: } } }; private void changeBtnText() { //当触发changeBtnText,会执行子线程方法,执行结束发送handler去主线程。 doSubThreadAction(); mhandler.sendEmptyMessageDelayed(ST_HANDLER_LICENSE_GET, 100); } }
组成部分:Message, Handler, MessageQueue, Looper
流程:
(1)主线程中创建handler对象,并重写handleMessage()方法。
(2)子线程更新UI,创建一个Message对象,通过handler将消息发送出去。之后这条消息会被添加到MessageQueue中等待被处理。而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回handler里的handleMessage()方法中。
(3)因为handler是在主线程中创建,所以handleMessage()也是在主线程中执行。
2. runOnUiThread(),实现原理同上handler流程。是异步消息处理的接口封装。
(1)activity_main
.xml <?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/runOnUIThread_btn" android:layout_width="40dp" android:layout_height="40dp" android:text="First Button" /> </android.support.constraint.ConstraintLayout> (2)MainActivity.java public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate: "); } @Override protected void onResume() { super.onResume(); final Button button = (Button) findViewById(R.id.runOnUIThread_btn); runOnUiThread(new Runnable() { @Override public void run() { //更新UI button的内容 button.setText("RunOnUIThread-Button"); } }); } }
3. AsyncTask
/**
* AsyncTask是个抽象类,需要子类继承它。
* AsyncTask第一个参数:需要传递参数到后台任务,void表示不需要
* AsyncTask第二个参数:表示用整型数据表示进度显示单位
* AsyncTask第三个参数:便是返回值的类型
*/
public class DownloadTask extends AsyncTask<Void, Integer, Boolean> { private ProgressDialog progressDialog; private Context context; public DownloadTask(ProgressDialog progressDialog, Context context){ this.progressDialog = progressDialog; this.context = context; } @Override protected void onPreExecute() { //该方法在后台任务开始执行前调用,用于一些界面上的操作,这里是弹出进度条。 progressDialog.show(); } @Override protected Boolean doInBackground(Void... voids) { //该方法执行耗时操作,在子线程中执行,不能更新UI。 while (true) { int downloadPercent = doDownload(); //如果想更新UI,调用publishProgress方法,它会自动去调用onProgressUpdate方法。 publishProgress(downloadPercent); if(downloadPercent >= 100){ break; } } return true; } @Override protected void onProgressUpdate(Integer... values) { progressDialog.setMessage("Download "+values[0] + "%"); } @Override protected void onPostExecute(Boolean result) { progressDialog.dismiss(); if (result) { Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "Download failed", Toast.LENGTH_SHORT).show(); } } private int doDownload() { //执行具体的download操作,在此为了方便返回一个常量值。 return 1; } }
作者:Susie
出处:https://www.cnblogs.com/zwting/p/9909466.html
欢迎转载,但还请尊重劳动果实,保留此段声明并注明原文链接。