【笔记】Android线程概括

来源:互联网 发布:东北大学网络教育官网 编辑:程序博客网 时间:2024/05/17 08:19

一、Handler


1.一个handler允许发送和处理Message和Ruanable对象,并且会关联到主线程的MessageQueue中。
2.每个handler都具有一个独立的线程,并且关联到一个消息队列的线程。也就是说,没当实例化一个hanlder的时候,它就承载着一个线程和消息队列的线程。
3.handler可以把Message或者Runnable压入到消息队列中,并且可以从消息队列中取出Message或者Runnable,进而操作它们。

Hndler的两个作用:

1.在工作线程中发送消息
2.在UI线程中获取。处理消息。

Handler把Message或者Runnable对象压入到消息队列中,有两大体系:

1.post:Post允许把一个Runnable对象入队到消息队列中。它具有的方法为:post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)。

2.sendMessage:sendMessage允许把一个包含数据的Message对象入队到消息队列中,它的方法有:sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTime(Message,long)、sendMessageDelayed
(Message,long)。

Handler --- post:

1.removeCallbacks(Runnable):从消息队列中移除一个Runnable对象。
2.boolean post(Runnable r):把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,立即执行。
   boolean postAtTime(Runnable r,long uptimeMillis):把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,在特定的时间执行。
   boolean postDelayed(Runnable r,long delayMillis):把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,延迟delayMills秒执行

post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)这些方法中的Runnable对象中,需要重写run()方法,一般这个run()方法中写入需要在UI线程(主线程)上的操作。

例子:

1.在UI线程(主线程上执行代码)
mes1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {//---此时创建时,在子线程上。不能在子线程上更新UI                    @Override                    public void run() {                        mHandler.post(new Runnable() {//---此时在UI线程上,post方法                            @Override                            public void run() {                                txt.setText("通过Post方法进行主线程上UI的更新!");                            }                        });                    }                }).start();            }        });        //延时执行        mes2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                txt.setText("通过延迟执行而进行主线程上UI的更新!");                            }                        },4004);                    }                }).start();            }        });

2.在子线程上执行获取网络上图片的操作:

onCreate()函数里面:
 dialog = new ProgressDialog(this);        dialog.setTitle("下载图片");        dialog.setMessage("下载中...,请稍等");        dialog.setCancelable(false);        //网络图片下载        load.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new myThread()).start();//开启子线程下载图片                //显示对话框                if(dialog != null){                   dialog.show();                }            }        });
创建一个Thread类:


public class myThread implements Runnable{        private static final String image_url = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";        @Override        public void run() {            HttpClient httpClient = new DefaultHttpClient();            HttpGet httpGet = new HttpGet(image_url);            HttpResponse httpResponse = null;            try {                httpResponse = httpClient.execute(httpGet);                if(httpResponse.getStatusLine().getStatusCode() == 200){                    byte[] data = EntityUtils.toByteArray(httpResponse.getEntity());                    final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                    mHandler.post(new Runnable() {                        @Override                        public void run() {                            image.setImageBitmap(bitmap);                        }                    });                    if(dialog != null && dialog.isShowing()){                       dialog.dismiss();                    }                }            } catch (IOException e) {                e.printStackTrace();            }        }    }

Handler --- sendMessage:

Handler中,与Message发送消息相关的方法有:
1.Message obtainMessage():获取一个Message对象。
   boolean sendMessage():发送一个Message对象到消息队列中,并在UI线程取到消息后,立即执行。
   boolean sendMessageDelayed():发送一个Message对象到消息队列中,在UI线程取到消息后,延迟执行。
   boolean sendEmptyMessage(int what):发送一个空的Message对象到队列中,并在UI线程取到消息后,立即执行。
   boolean sendEmptyMessageDelayed(int what,long delayMillis):发送一个空Message对象到消息队列中,在UI线程取到消息后,延迟执行。
   void removeMessage():从消息队列中移除一个未响应的消息。


整体例子:
package com.wangpei.hanlder;import android.app.Activity;import android.app.ProgressDialog;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import java.io.IOException;public class MainActivity extends Activity {    private Button mes1;    private Button mes2;    private TextView txt;    private Handler mHandler = new Handler();    private Button load;    private ImageView image;    private ProgressDialog dialog;    private static final  int IS_FINISH = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mes1 = (Button) findViewById(R.id.btn_mes1);        mes2 = (Button) findViewById(R.id.btn_mes2);        txt = (TextView) findViewById(R.id.txt);        image = (ImageView) findViewById(R.id.image);        load = (Button) findViewById(R.id.download);        dialog = new ProgressDialog(this);        dialog.setTitle("下载图片");        dialog.setMessage("下载中...,请稍等");        dialog.setCancelable(false);        //网络图片下载        load.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new myThread()).start();//开启子线程下载图片                //显示对话框                if(dialog != null){                   dialog.show();                }            }        });    }    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            if(msg.what == IS_FINISH){                byte[] data = (byte[]) msg.obj;                Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);                image.setImageBitmap(bitmap);                if(dialog != null && dialog.isShowing()){                    dialog.dismiss();                }            }        }    };    public class myThread implements Runnable{        private static final String image_url = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";        @Override        public void run() {            HttpClient httpClient = new DefaultHttpClient();            HttpGet httpGet = new HttpGet(image_url);            HttpResponse httpResponse = null;            try {                httpResponse = httpClient.execute(httpGet);                if(httpResponse.getStatusLine().getStatusCode() == 200){                    byte[] data = EntityUtils.toByteArray(httpResponse.getEntity());                    final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                    Message message = Message.obtain();                    message.obj = data;                    message.what = IS_FINISH;                    handler.sendMessage(message);                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

解析:
首先需要创建一个Handler:
private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            if(msg.what == IS_FINISH){                byte[] data = (byte[]) msg.obj;                Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);                image.setImageBitmap(bitmap);                if(dialog != null && dialog.isShowing()){                    dialog.dismiss();                }            }        }    };
这个Handler是用来处理接收到的消息。并且是在UI线程(主线程中执行的)

然后,在子线程中使用Message来发送消息:
      byte[] data = EntityUtils.toByteArray(httpResponse.getEntity());                          Message message = Message.obtain();      message.obj = data;      message.what = IS_FINISH;      handler.sendMessage(message);
其中,sendMessage就意在发送消息到hanlderMessa中。

更多的Message使用方法:

package com.wangpei.hanlder;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.PersistableBundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import org.w3c.dom.Text;/** * 作者:Wangpei on 2015/7/29 16:20 * 邮箱:460977141@qq.com */public class MainActivity2 extends Activity implements View.OnClickListener{    private Button btn1;    private Button btn2;    private Button btn3;    private Button btn4;    private Button btn5;    private TextView txt;   //创建一个Handler对象   private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            if(msg.what == 3 || msg.what == 5){                txt.setText("what = "+msg.what+",这是一个空消息!");            }else{                txt.setText("what = "+msg.what+",内容是:"+msg.obj.toString());            }        }    };    @Override    public void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        setContentView(R.layout.actvity_main2);        btn1 = (Button) findViewById(R.id.button);        btn2 = (Button) findViewById(R.id.button2);        btn3 = (Button) findViewById(R.id.button3);        btn4 = (Button) findViewById(R.id.button4);        btn5 = (Button) findViewById(R.id.button5);        txt = (TextView) findViewById(R.id.txt);        btn1.setOnClickListener(this);        btn2.setOnClickListener(this);        btn3.setOnClickListener(this);        btn4.setOnClickListener(this);        btn5.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            //使用Hanlder.sendMessage()发送消息            case R.id.button:{                Message message = Message.obtain();                message.obj = "使用Hanlder.sendMessage()发送消息";                message.what = 1;                handler.sendMessage(message);                break;            }            //使用Message.sendToTarget()发送消息,这类方法可以直接使用 Message.sendToTarget()方法发送消息到消息队列中,这是因为在Message对象中有一个私有的Handler类型的属性 Target,当时obtain方法传递进一个Handler对象的时候,会给Target属性赋值,当调用sendToTarget()方法的时候,实 际在它内部还是调用的Target.sendMessage()方法。            case R.id.button2:{                Message message = Message.obtain(handler);                message.what = 2;                message.obj = "使用Message.sendToTarget()发送消息";                message.sendToTarget();                break;            }            //发送空消息            case R.id.button3:{                handler.sendEmptyMessage(3);                break;            }            //使用Hanlder.sendMessage发送延迟消息            case R.id.button4:{                Message message = Message.obtain();                message.what = 4;                message.obj = "使用Hanlder.sendMessage发送延迟消息";                handler.sendMessageDelayed(message,4000);                break;            }           //发送延迟空消息            case R.id.button5:{                handler.sendEmptyMessageAtTime(5,4000);                break;            }        }    }}



0 0
原创粉丝点击