学习目的:1.了解android线程的使用 2.了解主线程与子线程区别 3.解析异步处理机制
主线程与子线程:所谓主线程,在Windows窗体应用程序中一般指UI线程,这个是程序启动的时候首先创建的线程。而子线程,一般指为了完成某个特殊任务,并行于主线程的其他线程。例如让一个窗体单独开一个线程,去远程数据库中取得数据资料,下载并且保存到本地文件中。
所以,主线程和子线程是构建于线程这个通用概念上的人为的习惯称呼,并不是什么官方的固有专用词语。
MainActivity(简而言之,为实现某个功能而创建爱的线程是子线程)
1.了解android线程的使用(例:在子线程更新UI)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class extends AppCompatActivity implements View.OnClickListener { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.text); Button changeText = (Button) findViewById(R.id.change_text); changeText.setOnClickListener(this); }
public void onClick(View v) { switch (v.getId()) { case R.id.change_text: new Thread(new Runnable() { public void run() { test.setText("Nice to meet you"); } }).start(); break; default: break; } }
}
|
logcat报错(说明不能在子线程更新UI)修改如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class extends AppCompatActivity implements View.OnClickListener {
public static final int UPDATE_TEXT = 1;
private TextView text;
private Handler handler = new Handler() {
public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: text.setText("Nice to meet you"); break; default: break; } }
};
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mai 大专栏 androidthreadtest
n); text = (TextView) findViewById(R.id.text); Button changeText = (Button) findViewById(R.id.change_text); changeText.setOnClickListener(this); }
public void onClick(View v) { switch (v.getId()) { case R.id.change_text: new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); } }).start(); break; default: break; } }
}
|
3.解析异步处理机制(Message MessageQueue Looper Handler四个部分)
异步处理机制的核心思想:一条Message经过如下转展调用,从子线程进入主线程,从而使不能更新UI变成可以更新UI
4.使用AsyncTask类(更方便的进行UI操作)
1
| class DownloadTask extends AsyncTask<Void Integer Boolean>{...}
|
三个参数
Params:执行AsyncTask需要传入的参数
Progress:后台任务执行时,需要在当前界面显示进度
Result:返回值类型
还需重写四个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class DownloadTask extends AsyncTask<Void Integer Boolean>{ @verride protected void onPreExecute(){ progressDialog.show(); } @verride protected Boolean doInBackground(void... Params){ try{ while(true){ int downloadPercent=doDownload(); publishProgress(downloadPercent); if(downloadPercent>=100){ break; } }catch(Exception e){ return false; } return true; }
} @verride protected void onProgressUpdata(Integer... values){ progressDialog.setMessage("Download"+values[0]+"%"); } @verride protected void onPostExecute(Boolean result){ progressDialog.dismiss(); if(result){ Toast.makeText(context,"Download Succeeded",Toast.LENGTH_SHORT).show();
}else{ Toast.makeText(context,"Download Failed",Toast.LENGTH_SHORT).show(); } } }
|
想要启动这个任务
1
| new DownloadTask().execute();
|