消息传递和异步任务

安卓中在子线成中更新UI会出现错误,为了确保UI显示的正确性,必须统一管理这些更改指令。怎么把子线程中的指令传递到主线程UI中,安卓提供了Handler消息机制。

handler message

void handleMessage(Message msg) handler中的消息处理方法,根据消息的不同做出不同的操作,一般被重写,自己定义消息的内容和操作内容。

final boolean hasMessage(int what)检查消息队列中是否有该消息。

Message obtainMessage()重用消息队列中的消息,第一次会生成一个新的实例。

sendEmptyMessage()发送一个空消息,起始内部还是发送的重用的Message对象,但是并没有指定message的其他内容。

final boolean sendMessge(Message msg)发送一个消息

final boolean sendMessage (Message msg ,long delayMillis)延迟发送message。

其实发送消息只是把他们放在了MessageQueue中,消息获取是Looper的事情。
在Looper的loop方法中有一个无限循环的代码块,他负责不停的从消息队列出取出消息。然后交给相应的handler进行处理。

//继承Handler 重写 handlerMessage方法 自定义对消息的处理方式
    class MyHandler extends  Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                //根据自己传进来的消息的变量来识别消息种类 不一定用msg.what
            }
        }
    }

    new Thread(new Runnable() {
        @Override
        public void run() {
        //需要处理的操作
        //处理完成之后handler发送消息到MessageQueue中
            Message msg=handler.obtainMessage();
            msg.what=1;
            myHandler.sendMessage(msg)
        }
    }).start();

Message类中一般使用的变量。可以完全把他当成一个简单类型来使用。

    public int what;

    public int arg1;

    public int arg2;

    public Object obj;

一个线程内有一个消息队列,一个Looper,可以由多个handler和多个消息。

异步任务AsyncTask

***public abstract class AsyncTask<Params, Progress, Result> 是一个抽象类,params启动任务时候需要传入的参数,progress后台完成任务进度值的类型,result执行任务完成返回值的类型。***

几个主要方法
- doInBackGround(Params…)在后台执行的任务,好比handler系列中子线程内的执行体。
- onProgressUpdate(Progress…)在主线程中运行,相当于handler中handleMessage(msg),比如在方法内设置textView.setText(“文字”)。
- publishProgress(Progress…)完成或完成部分内容向主线程发送消息,相当于handler.sendMessage()。
- onPreExecute 在执行后台操作前调用,做准备工作,比如页面显示进度条等等。
- onPostExecute(result )当线程完成后(doInBackground完成后)自动调用,通知主线程完成。相当于最后一次publishProgress和onProgressUpdate的结合体。

  • execute(params…)我们能够调用的方法。参数是我们需要传入线程的内容,与类声明是的类型保持一致。
//一个简单的按钮点击改变按钮文本的示例 
//handler message 方法 设置监听器 生成线程示例重写run()方法,线程的执行体,在线程执行完毕后发送消息。
  mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Message msg=myHandler.obtainMessage();
                    msg.what=1;
                    msg.obj="返回的文本信息";
                    myHandler.sendMessage(msg);
                }
            }).start();
        }
    });
//handler接受到消息进行识别处理。
    private  Handler myHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                //
                case 1:
                    mButton.setText(msg.obj.toString());
                    break;
            }
        }
    };
//AsyncTask  示例
//同样设置监听器 实例化 AsyncTask 启动 
     mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 myAsyncTask=new MyAsyncTask();
                  myAsyncTask.execute();
            }
        });
//自定义的AsyncTask 因为只是简单任务 所以有些方法可以补充重写
    class MyAsyncTask extends AsyncTask<Void,Integer ,String >{
        @Override
        protected String doInBackground(Void... voids) {
            //后台任务执行体
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //一次 或多次向主线程传递消息
            publishProgress(100);
            return "返回的文本信息";
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //简单任务,不需要前置操作。
        }

        @Override
        protected void onPostExecute(String String) {
            super.onPostExecute(String);
            //操作完成后 UI操作
            mButton.setText(String);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            //UI操作 耗时任务 进度型任务完成进度

        }
}

注意事项:

 1.必须在UI线程中创建AsyncTask实例。
 2.必须在UI线程中调用exectue()方法。
 3.重写的执行任务的方法,有系统负责,我们只需要调用execute方法。
 4.每个AsyncTask只能执行一次。

MARK(12)

五色令人目盲,五音令人耳聋,五味令人口爽,驰骋畋猎令人心发狂,难得之货令人行妨。是以圣人 ,为腹不为目,故去彼取此。

猜你喜欢

转载自blog.csdn.net/joy_chow/article/details/80961347