添加一個(gè)按鈕纠屋,并指定一個(gè)按鈕的點(diǎn)擊事件:
public void btnClicked(){
new Thread(new Runnable() {
//模擬一個(gè)網(wǎng)絡(luò)請(qǐng)求事件
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}
});
//handler.sendEmptyMessageDelayed(1,2000);//兩秒后發(fā)送消息
}
定義一個(gè)Handler對(duì)象:
private Handler handler = new Handler(){
//接收消息等待處理
@Override
public void handleMessage(Message msg) {
//回到主線(xiàn)程
switch (msg.what){
case 1:
button.setText("按鈕被改變了");
break;
default:
break;
}
}
};
點(diǎn)擊了按鈕后涂臣,實(shí)現(xiàn)了按鈕的文字改變?yōu)橹付ǖ膬?nèi)容。因?yàn)閁I控件的修改只能在主線(xiàn)程中執(zhí)行售担,所以當(dāng)我們?cè)谧远x的子線(xiàn)程中修改按鈕的文字時(shí)會(huì)導(dǎo)致程序運(yùn)行的崩潰赁遗。
使用Message類(lèi)發(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();
}
//在非主線(xiàn)程中更新UI控件的內(nèi)容
handler.post(new Runnable() {
@Override
public void run() {
button.setText("12df");
}
});
}
});
}
post的類(lèi)方法允許排列一個(gè)Runnable對(duì)象到主線(xiàn)程中,等待執(zhí)行族铆。
子線(xiàn)程中更新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ù)類(lèi)
/*AsyncTask的三個(gè)參數(shù)
* 參數(shù)一:執(zhí)行異步任務(wù)時(shí)需要傳入的三個(gè)的參數(shù)岩四,可用于在后臺(tái)任務(wù)中執(zhí)行
* 參數(shù)二:后臺(tái)任務(wù)執(zhí)行時(shí),若需要在前臺(tái)顯示進(jìn)度骑素,則使用這里指定的參數(shù)作為進(jìn)度單位
* 參數(shù)三:異步任務(wù)執(zhí)行結(jié)束后返回的結(jié)果
* */
class TestTask extends AsyncTask<Void,Void,String>{
//在異步線(xiàn)程里執(zhí)行
@Override
protected String doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = "asyncTask";
return string;
}
//接收子線(xiàn)程返回的字符串,切換到主線(xiàn)程執(zhí)行
@Override
protected void onPostExecute(String s) {
button.setText(s);
}
}
AyncTask類(lèi)常用的方法:
- onPreExecute():在后臺(tái)異步任務(wù)執(zhí)行開(kāi)始前調(diào)用炫乓;
- doInBackground():該方法里所有的代碼都在自線(xiàn)程中執(zhí)行,常用來(lái)處理一些耗時(shí)的操作献丑。任務(wù)結(jié)束后末捣,返回執(zhí)行的結(jié)果也可以不返回(視類(lèi)的第三個(gè)參數(shù)而定)。
- onProgressUpdate():接收后臺(tái)publishProgress(int)方法傳遞的參數(shù)创橄,用來(lái)更新前臺(tái)的UI控件;
- onPostExecute():后臺(tái)任務(wù)執(zhí)行接收后箩做,根據(jù)后臺(tái)執(zhí)行返回的結(jié)果更新前臺(tái)的UI內(nèi)容。
應(yīng)用實(shí)例
.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","準(zhǔn)備下載");
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Boolean doInBackground(Void... voids) {
Log.d("TAG","正在下載");
try {
while (true){
//每隔一秒下載10%
Thread.sleep(1000);
pregress+=10;
// 通知主線(xiàn)程當(dāng)前進(jìn)度是多少
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);//隱藏進(jìn)度條
}
else {
Log.d("TAG","下載失敗");
}
}
}
}
終端輸出:
03-28 18:37:34.840 619-619/com.example.felix.asynctaask D/TAG: 準(zhǔn)備下載
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: 下載成功