【笔记】Android线程概括

一、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;
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值