<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                為什么要用Handler: 出于性能優化考慮,Android的UI操作并不是線程安全的,這意味著如果有多個線程并發操作UI組件,可能導致線程安全問題。為了解決這個問題,Android制定了一條簡單的原則:只允許UI線程(亦即主線程)修改Activity中的UI組件。 當一個程序第一次啟動時,Android會同時啟動一條主線程,主線程主要負責處理與UI相關的事件,如用戶的按鍵事件、用戶接觸屏幕的事件、屏幕繪圖事件,并把相關的事件分發到相應的組件進行處理,所以主線程通常又叫做UI線程。 Handler的概念: 1)**執行計劃任務**,可以在預定的時間執行某些任務,可以模擬定時器 2)**線程間通信**。在Android的應用啟動時,會創建一個主線程,主線程會創建一個 消息隊列來處理各種消息。**當你創建子線程時,你可以在你的子線程中拿到父線程中 創建的Handler 對象,就可以通過該對象向父線程的消息隊列發送消息了**。由于Android要求在UI線程中更新界面,因此,可以通過該方法在其它線程中更新界面。 Handler類包含如下方法用于發送、處理消息: ? void handlerMessage(Message msg):處理消息的方法,該方法通常用于被重寫。 ? final boolean hasMessage(int what):檢查消息隊列中是否包含what屬性為指定值的消息。 ? sendEmptyMessage(int what):發送空消息 ? final boolean sendMessage(Message msg):立即發送消息,注意這塊返回值,如果message成功的被放到message queue里面則返回true,反之,返回false;(個人建議:對于這類問題不必主觀去記它,當實際使用時,直接查看源碼即可,源碼中有詳細的注釋) Handler的作用: (1)在一個線程中發送消息。 (2)在另一個線程中獲取、處理消息。 Handler處理的基本原理: 為了讓主線程能及時處理子線程發送的消息,顯然只能通過回調的方法來實現----開發者只要重寫Handler類中的方法,**當新啟動的線程發送消息時,消息會發送至與之關聯的MessageQueue,而Handler會不斷的從MessageQuere中獲取并處理消息**-----這將導致Handler類中處理消息的方法被回調。 在線程中使用Handler的基本步驟如下: 在被調用線程中完成以下內容: (1)調用 Looper的prepare()方法為當前線程創建Looper對象,創建Looper對象時,它的構造器會創建與之配套的MessageQueue。 (2)有了Looper之后,創建Handler子類的實例,重寫HandlerMessage()方法,該方法負責處理來自其它線程的消息。 (3)調用Looper的loop()方法啟動Looper。 注:若被調用線程是主線程類,由于系統自動為主線程創建了Looper的實例,因此第一、三步驟可省略,而只需要做第2步即可。 在調用線程中完成: (1)創建message,并填充內容。 (2)使用被調用類創建的Handler實例,調用sendMessage(Message msg)方法。 Handler 與線程的關系 Handler 一般運行于主線程內,也可以運行在子線程中,但是一定要創建Looper對象。主線程中Android已經為之創建了Looper對象 使用Handler的兩種常見情況: 1、只能在主UI中修改UI。但實際上,**有部分UI需要在子線程中控制其修改邏輯,因此子線程需要通過handler通知主線程修改UI**。這在游戲開發中尤其常見,比如需要讓新啟動的線程周期性的改變UI。、 **子線程通知主UI線程修改UI組件**的例子,新線程周期性的修改ImageView所顯示的圖片: **這個例子是Handler在主線程中獲取,處理消息,在子線程中發送消息** ~~~ public class HandlerTest extends Activity { // 定義周期性顯示的圖片的ID int[] imageIds = new int[] { R.drawable.java, R.drawable.ee, R.drawable.ajax, R.drawable.xml, R.drawable.classic }; int currentImageId = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView show = (ImageView) findViewById(R.id.show); final Handler myHandler = new Handler()//在主線程中,獲取,處理消息,更新UI組件,可以修改UI組件 { @Override public void handleMessage(Message msg) { // 如果該消息是本程序所發送的 if (msg.what == 0x1233) { // 動態地修改所顯示的圖片 show.setImageResource(imageIds[currentImageId++ % imageIds.length]); } } }; // 定義一個計時器,讓該計時器周期性地執行指定任務。子線程通知主線程修改UI組件,實現進程間通信 new Timer().schedule(new TimerTask() { @Override public void run() { // 發送空消息 myHandler.sendEmptyMessage(0x1233);在線程中發送消息 } }, 0, 1200); } } ~~~ 2、為避免ANR,**應該在子線程中執行耗時較長的操作,而此操作完成后,有可能需要通知主線程修改UI**。 **在子線程中執行耗時任務后,通知主線程修改UI組件**的例子:使用新進程計算質數,并用Toast顯示 **這個例子是在主線程中發送消息,在子線程中獲取,處理消息** ~~~ public class CalPrime extends Activity { static final String UPPER_NUM = "upper"; EditText etNum; CalThread calThread; // 定義一個線程類 class CalThread extends Thread { public Handler mHandler; public void run() { Looper.prepare();//創建Looper對象,每個線程使用Handler時都要有一個Looper對象 mHandler = new Handler()//在子線程中用handler獲取,處理消息 { // 定義處理消息的方法 @Override public void handleMessage(Message msg) { if(msg.what == 0x123) { int upper = msg.getData().getInt(UPPER_NUM); List<Integer> nums = new ArrayList<Integer>(); // 計算從2開始、到upper的所有質數 outer: for (int i = 2 ; i <= upper ; i++) { // 用i處于從2開始、到i的平方根的所有數 for (int j = 2 ; j <= Math.sqrt(i) ; j++) { // 如果可以整除,表明這個數不是質數 if(i != 2 && i % j == 0) { continue outer; } } nums.add(i); } // 使用Toast顯示統計出來的所有質數 Toast.makeText(CalPrime.this , nums.toString() , Toast.LENGTH_LONG).show(); } } }; Looper.loop();//啟動Looper } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); etNum = (EditText)findViewById(R.id.etNum); calThread = new CalThread(); // 啟動新線程 calThread.start(); } // 為按鈕的點擊事件提供事件處理函數 public void cal(View source) { // 創建消息 Message msg = new Message(); msg.what = 0x123; Bundle bundle = new Bundle(); bundle.putInt(UPPER_NUM , Integer.parseInt(etNum.getText().toString())); msg.setData(bundle); // 在主線程中向新線程中的Handler發送消息 calThread.mHandler.sendMessage(msg);//在主線程中發送消息 } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看