Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之handler詳解(一)

Android之handler詳解(一)

編輯:關於Android編程

1.Handler是什麼?

Handler是Android給我們提供的一套更新UI的機制,也封裝了一套消息處理的機制,可以發送消息,也可以通過它處理消息。

eg:Handler在Framework中常見,比如Activity的生命周期onCreate,onResume,onDestroy這些方法究竟在什麼時候被調用呢,其實查看Framework源碼就會發現,

所有的Activity回調方法都是通過Handler發送消息,根據不同的Message做相應的分支處理,告訴Framework去回調activity onCreate,onResume方法。

在Framework中,Activity的交互大部分都是用AMS(Activity Manager Service)做處理的。

在應用程序中,一個核心的類就是ActivityThread,ActivityThread中就是通過Handler接收到AMS給我們發送的Activity生命周期的一些管理,AMS發送一個啟動Activity的一 個實例,那麼我們整個ActivityThread接收到這個實例就會回調Activity onCreate方法。

回調機制就是通過Handler機制詳細的回調處理信息的。

2.為什麼要用Handler?

不用Handler機制是不行的。

Android在設計的時候就封裝了一套消息創建、傳遞、處理機制,如果不遵循這樣的機制就沒辦法更新UI信息,就會拋出異常信息。

異常就是不能在非UI線程中更新UI

3.Handler怎麼用呢?

下面是Google官方的API:

\

翻譯:

一個Handler 允許你發送和處理一個Message或者Runable對象,跟線程的MessageQueen進行關聯,每個Handler實例與一個線程進行綁定,這個線程是帶有MessageQueen的一個線程。當你創建一個新的handler的時候,默認會綁定到創建線程的MessageQueeen當中,從這點可以知道,它將要傳遞和處理消息並執行消息在MessageQueen當中,並從MessageQueen當中進行移除。

意思就是:創建一個Handler的時候會和默認的線程進行綁定,默認的線程中有個MessageQueen,MessageQueen字面上就是消息隊列的意思。

\

翻譯:Handler主要有兩個用途:一個是定時的發送Message和Runable對象,二是在一個線程當中處理並執行一個action,一個動作。

\

翻譯:當你創建一個應用程序的時候會創建一個進程,進程在Activity中就是一個UI線程(ActivityThread線程),在UI線程中,系統會默認的創建一個Looper,這個Looper和UI線程,MessageQueen有一定的聯系。。主線程主要是運行一個MessageQueen管理頂級的應用程序(Activity,BroadcastReceiver)。Activity,BroadcastReceiver默認創建在ActivityThread當中。

 

Handler的四種用法:

post(Runable)

postDelayed(Runable,long)

 

sendMessage

sendMessageDelayed

代碼示例1:post(Runable)

獲取一個textView控件,讓其5秒之後修改textView的內容(因為要5秒,所以啟用子線程)

 


public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); new Thread() { @Override public void run() { super.run(); try { Thread.sleep(5000); textView.setText("你好世界"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }

 


報錯:不能在非UI線程(子線程)中更新UI 所以使用handler從子線程發送消息到主線程更新UI

 

注意:Handler導入android:os的包

 

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);

        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(5000);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText("你好世界");
                        }
                    });

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}
代碼示例2:postDelayed(Runable,long)

 

淘寶上每隔一段時間定期換一張圖片的效果

 

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;
    private int images[] = {R.drawable.a, R.drawable.b, R.drawable.c};
    private int index;
    private Handler handler = new Handler();
    private MyRunable myRunable = new MyRunable();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);
        handler.postDelayed(myRunable, 1000);//調用

    }

    class MyRunable implements Runnable {
        @Override
        public void run() {
            index++;
            index = index % 3;//讓圖片循環播放
            imageView.setImageResource(images[index]);
            handler.postDelayed(myRunable, 1000);
        }
    }
}

代碼示例3:sendMessage

在子線程中用handler發送消息(sendMessage)給handler,handler會接收消息並打印出來

 

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    //重寫handleMessage方法接收發送過來的消息
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            textView.setText(msg.arg1 + " " + msg.arg2 + " " + msg.obj);
        }
    };

    class Person {
        private int age;
        private String name;

        @Override
        public String toString() {
            return "age==" + age + " " + "name==" + name;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
//                    Message message = new Message();
                    Message message = handler.obtainMessage();
                    message.arg1 = 88;
                    message.arg2 = 100;
                    Person person = new Person();
                    person.age = 15;
                    person.name = "小紅";
                    message.obj = person;
                    handler.sendMessage(message);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
//創建Message對象有兩種方法:

 

new Message返回一個message對象

handler.obtainMessage()返回一個message對象

查看源碼:

\ \

this指的是handler自己,target指消息發送給handler

handler發送消息也有兩種方式:

handler.sendMessage();

message.sendToTarget();

代碼示例4:handler移除消息,調用handler.removeCallbacks(myRunable)

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private ImageView imageView;
    private int images[] = {R.drawable.a, R.drawable.b, R.drawable.c};
    private int index;
    private Handler handler = new Handler();
    private MyRunable myRunable = new MyRunable();
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);
        findViewById(R.id.button).setOnClickListener(this);
        handler.postDelayed(myRunable, 1000);//調用

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.button:{
                handler.removeCallbacks(myRunable);
            }
        }
    }

    class MyRunable implements Runnable {
        @Override
        public void run() {
            index++;
            index = index % 3;//讓圖片循環播放
            imageView.setImageResource(images[index]);
            handler.postDelayed(myRunable, 1000);
        }
    }
}
代碼示例5:通過Callback接口攔截發送過來的消息,如果為true成功截獲不執行後邊的代碼,如果為false, 就執行

 

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button button;
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            Toast.makeText(MainActivity.this, "AAA", Toast.LENGTH_SHORT).show();
            return true;
        }
    }){
        @Override
        public void handleMessage(Message message) {
            Toast.makeText(MainActivity.this,"BBB", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
       handler.sendEmptyMessage(0);
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved