添加一個按鈕,并指定一個按鈕的點擊事件:
public void btnClicked(){
new Thread(new Runnable() {
//模擬一個網(wǎng)絡(luò)請求事件
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}
});
//handler.sendEmptyMessageDelayed(1,2000);//兩秒后發(fā)送消息
}
定義一個Handler對象:
private Handler handler = new Handler(){
//接收消息等待處理
@Override
public void handleMessage(Message msg) {
//回到主線程
switch (msg.what){
case 1:
button.setText("按鈕被改變了");
break;
default:
break;
}
}
};
點擊了按鈕后,實現(xiàn)了按鈕的文字改變?yōu)橹付ǖ膬?nèi)容。因為UI控件的修改只能在主線程中執(zhí)行,所以當我們在自定義的子線程中修改按鈕的文字時會導(dǎo)致程序運行的崩潰。
使用Message類發(fā)送消息
Message message = new Message();
String str = "Message";
message.obj = str;
message.what = 2;
handler.sendMessage(message);
消息接收處理:
case 2:
String str = (String) msg.obj;
button.setText(str);
break;
使用post方法
public void testPost(){
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//在非主線程中更新UI控件的內(nèi)容
handler.post(new Runnable() {
@Override
public void run() {
button.setText("12df");
}
});
}
});
}
post的類方法允許排列一個Runnable對象到主線程中,等待執(zhí)行。
子線程中更新UI控件內(nèi)容的其他方法:
runOnUiThread(new Runnable() {
@Override
public void run() {
button.setText("3dfs");
}
});
view控件+post方法
button.post(new Runnable() {
@Override
public void run() {
button.setText("sergs34");
}
});
AsyncTask異步任務(wù)類
/*AsyncTask的三個參數(shù)
* 參數(shù)一:執(zhí)行異步任務(wù)時需要傳入的三個的參數(shù),可用于在后臺任務(wù)中執(zhí)行
* 參數(shù)二:后臺任務(wù)執(zhí)行時,若需要在前臺顯示進度,則使用這里指定的參數(shù)作為進度單位
* 參數(shù)三:異步任務(wù)執(zhí)行結(jié)束后返回的結(jié)果
* */
class TestTask extends AsyncTask<Void,Void,String>{
//在異步線程里執(zhí)行
@Override
protected String doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = "asyncTask";
return string;
}
//接收子線程返回的字符串,切換到主線程執(zhí)行
@Override
protected void onPostExecute(String s) {
button.setText(s);
}
}
AyncTask類常用的方法:
- onPreExecute():在后臺異步任務(wù)執(zhí)行開始前調(diào)用;
- doInBackground():該方法里所有的代碼都在自線程中執(zhí)行,常用來處理一些耗時的操作。任務(wù)結(jié)束后,返回執(zhí)行的結(jié)果也可以不返回(視類的第三個參數(shù)而定)。
- onProgressUpdate():接收后臺publishProgress(int)方法傳遞的參數(shù),用來更新前臺的UI控件;
- onPostExecute():后臺任務(wù)執(zhí)行接收后,根據(jù)后臺執(zhí)行返回的結(jié)果更新前臺的UI內(nèi)容。
應(yīng)用實例
.xml文件
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btnClicked"
android:text="Hello World!" />
<ProgressBar
android:id="@+id/pb"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_centerInParent="true"
android:visibility="gone"
android:max="100"
style="?android:attr/progressBarStyleHorizontal"
/>
.java文件
public class MainActivity extends AppCompatActivity {
private Button button;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.btn);
progressBar = (ProgressBar) findViewById(R.id.pb);
}
public void btnClicked(View view){
new TestAsyncTask().execute();
}
class TestAsyncTask extends AsyncTask<Void,Integer,Boolean>{
int pregress;
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("TAG","準備下載");
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Boolean doInBackground(Void... voids) {
Log.d("TAG","正在下載");
try {
while (true){
//每隔一秒下載10%
Thread.sleep(1000);
pregress+=10;
// 通知主線程當前進度是多少
publishProgress(pregress);
//退出永久循環(huán)
if (pregress>=100){
break;
}
}
}
catch (Exception e){
return false;
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.d("TAG","已下載"+values[0]+“%”);
progressBar.setProgress(values[0]);
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean){
Log.d("TAG","下載成功");
progressBar.setVisibility(View.GONE);//隱藏進度條
}
else {
Log.d("TAG","下載失敗");
}
}
}
}
終端輸出:
03-28 18:37:34.840 619-619/com.example.felix.asynctaask D/TAG: 準備下載
03-28 18:37:34.853 619-3897/com.example.felix.asynctaask D/TAG: 正在下載
03-28 18:37:35.889 619-619/com.example.felix.asynctaask D/TAG: 已下載10%
03-28 18:37:36.901 619-619/com.example.felix.asynctaask D/TAG: 已下載20%
03-28 18:37:37.907 619-619/com.example.felix.asynctaask D/TAG: 已下載30%
03-28 18:37:38.939 619-619/com.example.felix.asynctaask D/TAG: 已下載40%
03-28 18:37:39.981 619-619/com.example.felix.asynctaask D/TAG: 已下載50%
03-28 18:37:41.019 619-619/com.example.felix.asynctaask D/TAG: 已下載60%
03-28 18:37:42.060 619-619/com.example.felix.asynctaask D/TAG: 已下載70%
03-28 18:37:43.106 619-619/com.example.felix.asynctaask D/TAG: 已下載80%
03-28 18:37:44.148 619-619/com.example.felix.asynctaask D/TAG: 已下載90%
03-28 18:37:45.192 619-619/com.example.felix.asynctaask D/TAG: 已下載100%
03-28 18:37:45.192 619-619/com.example.felix.asynctaask D/TAG: 下載成功