日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载

發布時間:2023/12/10 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

效果圖:

  

?

?

?

?

1、activity_main.xml

  描述:定義了六個按鈕

    

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/showNumber"android:textSize="35dp"android:gravity="center"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="0"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始計數"android:onClick="doStart"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="結束計數"android:onClick="doStop"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始計數2"android:onClick="doStart2"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="結束計數2"android:onClick="doStop2"android:layout_weight="1"/></LinearLayout><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="子線程和子線程之間的通信"android:onClick="test_1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="異步任務"android:onClick="test_2"/> </LinearLayout>

2、MainActivity.java

package com.nf.android_thread;import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.view.View; import android.widget.TextView; import android.widget.Toast;public class MainActivity extends Activity {
  //用來顯示數字
private TextView showNumber;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);showNumber = (TextView)findViewById(R.id.showNumber);//彈出提示Toast.makeText(this,"程序開始",Toast.LENGTH_SHORT).show();//將耗時操作放到子線程中,將不會阻塞主線程運行new Thread(new Runnable() {@Overridepublic void run() {try{
            //線程休眠20秒Thread.currentThread().sleep(
20000);}catch (InterruptedException e){e.printStackTrace();}}}).start();Toast.makeText(this,"程序結束",Toast.LENGTH_SHORT).show();}//聲明一個主線程的Handler對象
  /*
    handler:
    消息的封裝者和處理者,handler負責將需要傳遞的信息封裝成Message,通過調用handler對象的obtainMessage()來實現;
    將消息傳遞給Looper,這是通過handler對象的sendMessage()來實現的。繼而由Looper將Message放入MessageQueue中。
    當Looper對象看到MessageQueue中含有Message,就將其廣播出去。
    該handler對象收到該消息后,調用相應的handler對象的handleMessage()方法對其進行處理。
  
  */
  /*
    Message:
    消息對象,Message Queue中的存放的對象。一個Message Queue中包含多個Message。
    Message實例對象的取得,通常使用Message類里的靜態方法obtain(),該方法有多個重載版本可供選擇;
    它的創建并不一定是直接創建一個新的實例,而是先從Message Pool(消息池)中看有沒有可用的Message實例,存在則直接取出返回這個實例。
    如果Message Pool中沒有可用的Message實例,則才用給定的參數創建一個Message對象。
    調用removeMessages()時,將Message從Message Queue中刪除,同時放入到Message Pool中。
    除了上面這種方式,也可以通過Handler對象的obtainMessage()獲取一個Message實例。
  */
  /*
    MessageQueue
    是一種數據結構,見名知義,就是一個消息隊列,存放消息的地方。每一個線程最多只可以擁有一個MessageQueue數據結構。
    創建一個線程的時候,并不會自動創建其MessageQueue。通常使用一個Looper對象對該線程的MessageQueue進行管理。
    主線程創建時,會創建一個默認的Looper對象,而Looper對象的創建,將自動創建一個Message Queue。
    其他非主線程,不會自動創建Looper,要需要的時候,通過調用prepare函數來實現。
  */
  /*
    Looper:
    是MessageQueue的管理者。每一個MessageQueue都不能脫離Looper而存在,Looper對象的創建是通過prepare函數來實現的。
    同時每一個Looper對象和一個線程關聯。通過調用Looper.myLooper()可以獲得當前線程的Looper對象創建一個Looper對象時,會同時創建一個MessageQueue對象。
    除了主線程有默認的Looper,其他線程默認是沒有MessageQueue對象的,所以,不能接受Message。
    如需要接受,自己定義一個Looper對象(通過prepare函數),這樣該線程就有了自己的Looper對象和MessageQueue數據結構了。
    Looper從MessageQueue中取出Message然后,交由Handler的handleMessage進行處理。
    處理完成后,調用Message.recycle()將其放入Message Pool中。
  */private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);
       //判斷來自哪個線程的handler
if (msg.what == 1){
          //給ui控件綁定計算得到的數字showNumber.setText(msg.arg1
+"");}}};//開始計數int number = 1;boolean isRun;public void doStart(View view){isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){//將計數發送給UI線程【Main Thread】
            //?這里的數據data我們必須發送給UI的主線程,所以我們通過Message的方式來做橋梁。Message message = Message.obtain();
            //設置handler版本message.what
= 1;message.arg1 = number;//如果將消息發給主線程呢
            //調用handler的sendMessage()方法,將得到的數字傳進去 handler.sendMessage(message);SystemClock.sleep(1000);number++;}}}).start();}
   //當點擊停止按鈕時,將isRun設置為false,并將number設置為1
public void doStop(View view){isRun = false;number = 1;}

public void doStart2(View view){isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){//UI多線程中不能直接更新UIrunOnUiThread(new Runnable() {@Overridepublic void run() {showNumber.setText(number+"");}});number++;SystemClock.sleep(1000);}}}).start();}public void doStop2(View view){doStop(view);}public void test_1(View view){Intent intent = new Intent(this,Thread2Activity.class);startActivity(intent);}public void test_2(View view){Intent intent = new Intent(this,AsyncTaskActivity.class);startActivity(intent);} }

3、activity_thread2.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_thread2"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/showNumber"android:text="0"android:textSize="40dp"android:gravity="center"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始計算"android:onClick="doStart"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="停止計算"android:onClick="doStop"/> </LinearLayout>

4、Thread2Activity.java

package com.nf.android_thread;import android.app.Activity; import android.app.Notification; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.util.Log; import android.view.View; import android.widget.TextView;import java.util.Random;public class Thread2Activity extends Activity {private TextView showNumber;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_thread2);showNumber = (TextView)findViewById(R.id.showNumber);}
  
private Handler mainHandler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);if (msg.what == 2){showNumber.setText(msg.arg1+"");}}};boolean isRun;int count = 0;Handler myHandler;public void doStart(View view){//用來處理數字平方的線程new Thread(new Runnable() {@Overridepublic void run() {
          //Android中的Looper類,是用來封裝消息循環和消息隊列的一個類,用于在android線程中進行消息處理。
          //handler其實可以看做是一個工具類,用來向消息隊列中插入消息的。Looper.prepare();
//準備好一個消息隊列myHandler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);if (msg.what==1){Log.i("Thread2:","消息:"+msg.arg1);int number = msg.arg1*msg.arg1;Message message = Message.obtain();message.what = 2;message.arg1 = number;mainHandler.sendMessage(message);}}};Looper.loop();//循環 }}).start();
//開始計數的線程isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){int rand = new Random().nextInt(100);//獲得隨機數Log.i("Thread1:","隨機數:"+rand);//發生消息到處理數字的線程Message msg = Message.obtain();msg.what = 1;msg.arg1 = rand;myHandler.sendMessage(msg);//通過Handler將消息發送到線程2count++;if (count>100)break;SystemClock.sleep(1000);}}}).start();}public void doStop(View view){isRun = false;count = 0;} }

5、activity_async_task.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_async_task"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ProgressBarandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/progressBar"style="@android:style/Widget.ProgressBar.Horizontal"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始下載"android:onClick="doStart"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="結束下載"android:onClick="doStop"/> </LinearLayout>

6、AsyncTaskActivity.java

package com.nf.android_thread;import android.app.Activity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast;public class AsyncTaskActivity extends Activity {
  //進度條
private ProgressBar progressBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_async_task);progressBar =(ProgressBar)findViewById(R.id.progressBar);}MyAsyncTask task;//開啟一個異步任務執行下載public void doStart(View view){
     //當點擊開始按鈕后,實例化一個異步任務task
= new MyAsyncTask();
      task.execute(
0);}//結束異步下載任務public void doStop(View view){task.cancel(true);}//構建一個異步任務class MyAsyncTask extends AsyncTask<Integer,Integer,String>{//必須的,執行異步操作
     //屬于后臺操作
     /**??
?????   *?這里的Integer參數對應AsyncTask中的第一個參數???
????   ?*?這里的String返回值對應AsyncTask的第三個參數??
????? *?該方法并不運行在UI線程當中,主要用于異步操作,所有在該方法中不能對UI當中的空間進行設置和修改??
????? *?但是可以調用publishProgress方法觸發onProgressUpdate對UI進行操作??
???? ?*/?? @Overrideprotected String doInBackground(Integer...integers){for (int i=1;i<100;i++){publishProgress(i);//刷新進度SystemClock.sleep(100);}return "success";}//做一些初始化的操作
     //該方法運行在UI線程當中,并且運行在UI線程當中?可以對UI空間進行設置??@Override
protected void onPreExecute(){super.onPreExecute();Toast.makeText(AsyncTaskActivity.this,"開始下載",Toast.LENGTH_SHORT).show();}//得到后臺操作返回的結果
    
/**??

? ?    *?這里的String參數對應AsyncTask中的第三個參數(也就是接收doInBackground的返回值)??

?????   *?在doInBackground方法執行結束之后在運行,并且運行在UI線程當中?可以對UI空間進行設置??

?????  */?

@Overrideprotected void onPostExecute(String s){super.onPostExecute(s);if ("success".equals(s)){Toast.makeText(AsyncTaskActivity.this,"下載完畢",Toast.LENGTH_SHORT).show();}else{Toast.makeText(AsyncTaskActivity.this,"下載失敗",Toast.LENGTH_SHORT).show();}}
     //更新進度
     

      /**??

?????    *?這里的Intege參數對應AsyncTask中的第二個參數??

?????    *?在doInBackground方法當中,每次調用publishProgress方法都會觸發onProgressUpdate執行??

?????    *?onProgressUpdate是在UI線程中執行,所以可以對UI空間進行操作??

?????    */??

@Overrideprotected void onProgressUpdate(Integer... values){super.onProgressUpdate(values);//更新進度條progressBar.setProgress(values[0]);}} }

?

轉載于:https://www.cnblogs.com/zn615/p/8244844.html

總結

以上是生活随笔為你收集整理的Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。