android 6.21线程的概念

两种实现方式:

  1. extends Thread类,复写run();
  2. 实现Runnable接口,复写run()方法,获得的对象传入Thread类构建新线程的构造方法中。

安卓线程分类

  1. MainThread:UI线程运行UI相关的代码。
  2. WorkerThread:其他的代码由WokerThread负责。
  3. 原则上UI相关的修改不允许在WorkerThread上进行修改,但是有些例外的比如修改progressBar的progress()方法。

ANR问题:application not responding

在一个应用程序中主线程通常用于接受用户的输入,并将运算的结果反馈出来
所以主线程不能阻塞,对于一些可能产生阻塞的操作必须放置在WorkerThread中。

如何将workerThread中的问题反馈到MainThread中

Handler(管理者)

Handler运行原理:队列中存放数据对象,具有先进先出的顺序,队列中存放着大量数据,每个都是一个对象,Handler负责将对象加入到消息队列中
1. 使用obtainMessage()方法获得消息对象,使用msg.what复制消息对象。
2. 使用sendMessage方法发送消息到队列中。
Looper(循环器):从消息队列头部不断中取出对象,消息队列中无消息对象时会等待。取出的对象交给Handler处理。
1. 构建一个内部类继承Handler,并且重写其中的handleMessage方法。
2. 这个内部类的Handler对象承担了发送和处理消息的作用,使用int what = msg.what;将Looper接受到的对象取出如何重写handleMessage方法看自己意图。
看我没写调用对象的handleMessage方法,说明是自动 调用的

package com.example.handler01;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.io.FileReader;
import java.security.PrivateKey;

public class MainActivity extends AppCompatActivity {

    Button button;
    private FirstHandler firstHandler;

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

        button = (Button) findViewById(R.id.button);

        firstHandler = new FirstHandler();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                当用户点击按钮时,生成一个message对象将其发送出去
                //obtainMessage()方法生成一个message对象

                Message msg = firstHandler.obtainMessage();
//为message初始化
                msg.what = 2;
                //发送message
                firstHandler.sendMessage(msg);
//lLooper将消息对象取出,找到与消息对象对应的Handler对象,此处为firstHandler,然后调用Handler对象的handleMessage
                //方法处理消息对象。
            }
        });
    }

    class FirstHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
           int what = msg.what;
            Log.d("msg", what + "");
        }
    }
}

Handler实现线程之间的通信

  1. 从WorkerTread()中发送消息到MainThread()
package com.example.handler02;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Button button;
    private TextView textView;
    private MyHandler handler;

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

        textView = (TextView) findViewById(R.id.text_view);
        button = (Button) findViewById(R.id.button);
        handler = new MyHandler();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                InternetThread t = new InternetThread();
                t.start();
            }
        });
    }

    class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            //获取当前线程的名字,在主线程中通过handleMessage处理数据
            Log.d("msg","===currentThread is===" +Thread.currentThread().getName() );
            String s =(String) msg.obj;
            textView.setText(s);
        }
    }

    class InternetThread extends Thread {

        @Override
        public void run() {

            Log.d("msg","===currentThread is===" +Thread.currentThread().getName() );
            try {
                //模拟访问网络,休眠2秒钟
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //模拟网络中的数据
            String s = "网络数据";
            //在工作线程中获取数据并发送
            Message msg = handler.obtainMessage();
            //obj用于发送对象
            msg.obj = s;
            handler.sendMessage(msg);

        }
    }
}
  1. 从主线程中向workerThread发送消息
    1. 在WokerThread准备Looper对象,调用prepare()方法
    2. 在WokerThread当中生成Handler对象,然后调用Loop()方法
    3. 在MainThread中发送消息
      由此看出主线程直接执行prepare和loop()方法
package com.example.handler03;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private Button button;
    private Handler handler;

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

        button = (Button) findViewById(R.id.send_msg);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message msg = handler.obtainMessage();
                msg.what = 2;
                handler.sendMessage(msg);
                Log.d("msg", Thread.currentThread().getName() + "--发送了消息对象");

            }
        });

        WokerThread t = new WokerThread();
        t.start();
    }

    class WokerThread extends Thread {

        @Override
        public void run() {
            //准备Looper对象
            Looper.prepare();
            //生成一个handler对象
            handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    Log.d("msg", Thread.currentThread().getName() + "收到了message对象");
                }
            };
        //调用Looper类的Loop()方法后,Looper对象会不断的从消息队列中
            //取出消息对象,然后调用WokerThread线程中的handleMessage()方法处理对象,如果没有对象传入则该线程阻塞
            Looper.loop();
        }
    }
}

首次安卓源代码之旅

ThreadLocal类和基本思路

  1. 执行ThreadLocal对象的set(Object obj)方法将会备份一个当前线程对象,然后存储为和变量值相对应的键值对。
  2. 执行get()方法返回一个和当前线程对象对应的的变量的值。

思路:Looper.prepare()生成一个looper对象和对应的消息队列对象,调用TreadLocal的set()方法将线程对象和looper对象存储成一个本地线程的键值对。
new Handler对象是将looper对象取出赋值给Handler类的mlooper成员变量,建立起了关系。

loop()方法

looper()方法中首先调用myLooper()方法(其中通过sThreadLocal.get()方法获取了当前线程对应 的Looper对象)如果为空的说明没有调用prepare()方法,然后生成了一个消息队列,在一个for(;;)循环中生成一个消息对象,调用了一个消息队列的next()方法,可能返回null or message instance,so if msg == null, the loop() will end ,the message queue will quit ,and then ,msg.target.dispatchMessage(msg); target is an obj of Handler,and the dispatchMessage() method just call the handleMessage() method to handle the message. we use handler.obtainMessage to get a message , when we use handler = new Handler(),we call the mLooper = Looper.myLooper 获得了当前线程的looper对象与Handler建立起连接,一个Looper和一个messagequeue在prepare方法中相对应,使用handler生成message对象的target属性就是handler的值

handler的post方法

直接调用Runnable的run方法

package com.example.handler04;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private Button button;
    private Handler handler = new Handler();

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

        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyThread m = new MyThread();
                m.start();
            }
        });
    }

    class MyThread extends Thread {
        @Override
        public void run() {

            handler.post(new Runnable() {
                /*public final boolean post(Runnable r)
                {
                    return  sendMessageDelayed(getPostMessage(r), 0);
                }*/
                // getPostMessage:1.获得一个message对象,2将r对象赋值给callback属性
                //返回一个message对象
                //sendMessageDelayed()将消息延时发送
                //主线程在接受到r对象后,调用了loop()方法,相当于调用了dispatchMessage()方法,因为此时callBack不为空
                //所以调用了handleCallback方法直接调用了Runnable的run()方法。
                @Override
                public void run() {
                    Log.d("thread", "current thread name is-- " + Thread.currentThread().getName());
                }
            });
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值