Android 学习系列 - 线程模型

504 查看

线程模型

  1. android UI 线程

  2. 如何使用 child-process

ANR 错误

由于单线程而导致的ANR错误: ANR错误(Application Not Responding),指主UI进程被阻塞超过5秒钟而出现的错误,它会终止程序的正常运行,我们要避免它 ,而产生ANR错误的原因就是:单线程。

    public class MainActivity extends Activity {
        private Button btn;
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn=(Button) findViewById(R.id.btn);
            btn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int count=0;
                    while(count<1000){
                        count++;
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }); 
        }
    }

改为

    private Thread thread;
    thread=new Thread(new Runnable() {
        @Override
        public void run() {
            int count=0;
            while(count<1000){
                count++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(count);
            }
        }
    });
    thread.start();//启动线程
    thread.stop();//停止线程

但如果用这个线程来更新UI同样会遇到错误

Android线程之间的通信——Handler

其实,Android线程之间的通信不只是Handler,还需要Message,MessageQueue,Looper的相互使用,Android线程通信模型如下:

Thread ->[handler] -> Loop(message|> messageQueue) <- UI Thread(main thread)

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
    private Button btn_start,btn_stop;
    private TextView tv;
    private int i=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_start=(Button) findViewById(R.id.button1);
        btn_stop=(Button) findViewById(R.id.button2);
        tv=(TextView) findViewById(R.id.textView1);
        btn_start.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //开始发送消息
                handler.post(runnable);
            }
        });
        btn_stop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //停止发送消息
                handler.removeCallbacks(runnabl);
            }
        });
    }
    //创建新的线程
    private Runnable runnable=new Runnable() {
        @Override
        public void run() {
            i++;
            //使用Message封装非UI线程的消息
            Message m=new Message();
            //使用Message的arg1属性或者arg2属性传递int类型的消息效率高
            m.arg1=i;
            //使用Handler发送消息
            handler.sendMessage(m);
        }
    };
    @SuppressLint("HandlerLeak")
    private Handler handler=new Handler(){
        public void handleMessage(Message m){
            System.out.println(m.arg1);
            String str=m.arg1+"";
            tv.setText(str);
            handler.post(runnable);
        }
    };
}
  1. Message:即要传递的消息;

  2. MessageQueue:存放消息的队列;

  3. Looper:用于创建MessageQueue以及循环使用其中的Message;

  4. Handler:用于消息的传递了;

1、handler
2、Activity.runOnUIThread(Runnable)
3、View.Post(Runnable)
4、View.PostDelayed(Runnabe,long)
5、AsyncTask

  1. Thread , Runnable

AsyncTask

// <!-- MainActivity -->
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
    private Button btn1,btn2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn1=(Button) findViewById(R.id.button1);
        btn2=(Button) findViewById(R.id.button2);
        btn1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建AsyncTask并执行
                new MyAsyncTask().execute();
            }
        });
        btn2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("Hello To EveryOne");
            }
        });
    }
}

// <!--  MyAsyncTask.java  -->
import android.os.AsyncTask;
/**
 * 在后台创建线程,不会出现卡屏现象
 * @author asus
 */
public class MyAsyncTask extends AsyncTask<Void, Void, String>{
    //核心方法,在后台启动一个线程
    @Override
    protected String doInVoid(params) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}