背景知识
说明:1、参考资料《第一行代码》 2、做一下笔记, 备查
Android 异步消息机制实现UI处理
1、 Android的UI也是线程不安全的,所以必须在主线程更新UI 否则报错
2、 Android的异步消息处理机制
4个部分:Message、Handler、MessageQueue 和Looper
①Message:Message可以在携带少量信息,用于不同线程之间的消息传递
②Handler:消息处理者。发送消息一般使用 Handler的sendMessage()方法,发出的消息经过一系列处理后,最终会传递到HandlerdehandleMessahe()方法中。
③MessageQueue: 消息队列。用于存放Handler发送的消息,这些消息位于消息队列中,等待被处理。每个线程只有一个MessageQueue对象
④Looper:MessageQueue的管家, 调用Looperdeloop()方法后,就会进入无限循环,然后发现每当MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handleMessage()方法中。每个线程也只有一个Looper对象
补充:一般会在主线程创建一个继承了Handler的子类的实例, 然后重写其handleMessage()方法 。 在子线程中就直接用Handler调用sendMessage(Message msg) 就可以了
AsyncTask接口的实现()
1、AsyncTask对异步消息处理机制实现了进一步封装, 你可以更简单的从子线程切换到主线程
2、AsyncTask是抽象类,public abstract classAsyncTask<Params, Progress, Result> extends Object 。
继承时,需要指定3个泛型参数。
Params 在执行AsyncTask时需要传入的参数,用于在后台任务中使用
Progress 用于显示当前进度,用泛型指定进度单位
Result 执行结果的返回值类型
注意:Params 不能为空 , 我用Android Studio 2.3.3会报错
3、 需要重写的常用方法
4、小结:在doInBackground()方法中执行具体的耗时任务,在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务的收尾
代码实例
Mainactivity.java
程序功能:点击Button 修改textView + 一个虚拟的下载任务(注释部分)
package com.lfork.a98620.androidthreadtest;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
publicstatic final int UPDATE_TEXT= 1;
privateTextView text;
//Android异步消息机制实现UI处理 runOnUiThread()方法就是一个封装好的例子
private Handler handler = newHandler(){
@Override
publicvoid handleMessage(Message msg) {
switch(msg.what) {
case UPDATE_TEXT:
//进行UI操作
String str = "nice to meetyou";
text.setText(str);
break;
default:
break;
}
}
};
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button change = (Button)findViewById(R.id.btn_nice);
text= (TextView) findViewById(R.id.hello);
change.setOnClickListener(new View.OnClickListener() {
@Override
publicvoid onClick(View view) {
new Thread(newRunnable() {
@Override
publicvoid run() {
// String str = "nice to meet you";
// text.setText(str);
Message message = newMessage();
message.what =UPDATE_TEXT;
handler.sendMessage(message);
}
}).start();
}
});
}
}
//启动任务的时候就执行 new DownloadTask().execute()即可 虚构的任务
//class DownloadTask extends AsyncTask<Integer, Integer, Boolean> {
//
//
// @Override
// protected void onPreExecute() {
// // progressDialog.show();
// // 显示进度对话框
// }
//
//
// @Override
// protected BooleandoInBackground(Integer... integers) {
//
// try {
// while (true) {
// int downloadPercent = doDownload();//虚构的方法
// publishProgress(downloadPercent);
//
// if (downloadPercent>= 100) {
// break;
// }
// }
// } catch (Exception e) {
// return false;
// }
//
// return null;
// }
//
// @Override
// protected voidonProgressUpdate(Integer... values) {
// //在这里更新下载进度
// progressDialog.setMessage("Downloaded" + values[0] +"%");
// }
//
// @Override
// protected voidonPostExecute(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();
// }
//
// }
//}
布局文件
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.lfork.a98620.androidthreadtest.MainActivity">
<Button
android:id="@+id/btn_nice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/change_textview"
android:textAllCaps="false"/>
<TextView
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>
</LinearLayout>