Android學(xué)習(xí)筆記之多線(xiàn)程間的異步通信

添加一個(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: 下載成功
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末妥畏,一起剝皮案震驚了整個(gè)濱河市邦邦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌醉蚁,老刑警劉巖燃辖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異网棍,居然都是意外死亡黔龟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)滥玷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)氏身,“玉大人,你說(shuō)我怎么就攤上這事惑畴〉靶溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵如贷,是天一觀的道長(zhǎng)陷虎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)杠袱,這世上最難降的妖魔是什么泻红? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮霞掺,結(jié)果婚禮上谊路,老公的妹妹穿的比我還像新娘。我一直安慰自己菩彬,他們只是感情好缠劝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著骗灶,像睡著了一般惨恭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耙旦,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天脱羡,我揣著相機(jī)與錄音,去河邊找鬼。 笑死锉罐,一個(gè)胖子當(dāng)著我的面吹牛帆竹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脓规,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼栽连,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了侨舆?” 一聲冷哼從身側(cè)響起秒紧,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挨下,沒(méi)想到半個(gè)月后熔恢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡臭笆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年绩聘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耗啦。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凿菩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出获黔,到底是詐尸還是另有隱情玷氏,我是刑警寧澤块饺,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布屉佳,位于F島的核電站诅诱,受9級(jí)特大地震影響炮沐,放射性物質(zhì)發(fā)生泄漏玉雾。R本人自食惡果不足惜驹碍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望延刘。 院中可真熱鬧播掷,春花似錦件炉、人聲如沸景描。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)弄唧。三九已至,卻和暖如春从媚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背紧憾。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工憔四, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人般眉。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓了赵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親煤篙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斟览,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容