首页 > 代码库 > android入门 — 多线程(一)

android入门 — 多线程(一)

技术分享

  android中的一些耗时操作,例如网络请求,如果不能及时响应,就会导致主线程被阻塞,出现ANR,非常影响用户体验,所以一些耗时的操作,我们会想办法放在子线程中去完成。

  android的UI操作并不是线程安全的,所以多个线程并发操作UI组件的时候,则可能导致线程安全问题。为了解决这个问题,android只允许UI线程修改UI组件。

  

public class MainActivity extends AppCompatActivity
{
    TextView textView;
    Button changeText;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        changeText = (Button)findViewById(R.id.btn);
        textView = (TextView)findViewById(R.id.textView);
        changeText.setOnClickListener(this);
    }

    public void change(View view)
    {
        switch (view.getId())
        {
            case R.id.btn:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("被改变了");
                    }
                }).start();
                break;
            default:
                break;
        }
    }
}

  在xml中定义了一个按钮和一个TextView,当点击按钮的时候,开启子线程去更改TextView中的文字,但是在编译的时候是无法通过的,因为不允许在子线程中直接对UI线程中组件进行操作。

  需要借用Handler来实现子线程更新UI组件的功能。

public class MainActivity extends AppCompatActivity
{

    private TextView textView;
    private Handler handler = new Handler()
    {
        //接收的是消息队列中的msg
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case 0x0001:
                    int index = msg.arg1;
                    textView.setText(index + "");
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.textView1);
    }

    public void changeNumber(View view)
    {
        switch (view.getId())
        {
            case R.id.btn:
                new Thread()
                {
                    public void run()
                    {
                        for(int i = 0; i < 10; i++)
                        {
                            Message msg = new Message();
                            //msg.what是必不可少的,需要用来做判定
                            msg.what = 0x0001;
                            msg.arg1 = i;
                            handler.sendMessage(msg);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
                break;
        }
    }
}

  

 

MessageQueue消息队列

  android采用的是MessageQueue机制保证线程间通信。

  MessageQueue是一个消息队列,用来存放通过Handler发布的消息,Android在第一次启动程序的时候会默认为UI线程创建一个关联的消息队列,用来管理程序的组件,如Activity、BroadcastReceiver、Service等。

 

Handler消息传递机制

  工作线程通过handler对象和主线程进行通信

  Handler对象所有工作都在主线程中执行

  Handler类需要实现handleMessage()方法,来处理消息队列中取出的Message对象

  handleMessage()方法由主线程调用,可以在需要的时候更新UI线程,但是必须确保此方法快速完成,因为其他的UI操作会等待它完成才能执行

 

技术分享

  

技术分享

 

android入门 — 多线程(一)