安卓中一个程序跑起来叫进程,进程中至少有一个主线程。主线程用于处理用户的触摸操作和将触摸操作事件分发给响应的控件。如果进行消耗时间操作,下载,磁盘读取文件,不润许在主线程操作,只能在工作线程操作。主线程向工作线程发送消息和数据,工作线程也会时时反馈给主线程。线程通信:多个线程互相收发消息和数据。
安卓规定只有主线程才能修改UI界面和控件(除了进度条可以在工作线程修改),如果工作线程想修改UI界面则只能通知主线程进行修改。
Handler:句柄,手柄,遥控器,操作板。
mainActivity:
package com.sxt.day06_01; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { Handler mHandler; private static final int DOWNLOADING=1;//下载中,内部类中使用所以用静态类型, private static final int DOWNLOAD_FINISH=10;//下载完成 ProgressBar mProgressBar; TextView mtvProgress; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); setListener(); initHandler(); } private void initHandler() { //主线程处理消息 mHandler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case DOWNLOADING: mtvProgress.setText(msg.arg1+"%"); break; case DOWNLOAD_FINISH: Toast.makeText(MainActivity.this, "下载完成", 2000).show(); break; } } }; } private void setListener() { findViewById(R.id.btnStartDownload).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread(){//创建线程(工作线程) public void run() { for(int i=1;i<=100;i++){ SystemClock.sleep(20); mProgressBar.setProgress(i);//这个控件可以在工作线程修改 //没改变一次发送一个消息,发送100次,发送到Message的队列中, Message msg=Message.obtain();//静态方法获取message,从线程池中取一个对象,线程池是内存的一个缓冲区域,如果第一次没有Message对象会new一个,使用完以后不会销毁,下次直接从池子中取,线程池最多放10个, msg.what=DOWNLOADING;//what属性是消息的类型,整型。 msg.arg1=i;//arg1,arg2也是整型,还有一个obj属性是Object类型。 mHandler.sendMessage(msg);//发送消息给主线程,显示百分比 } //循环完以后发送一个结束的消息 Message msg=Message.obtain(); msg.what=DOWNLOAD_FINISH; mHandler.sendMessage(msg); }; }.start(); } }); } private void initView() { mProgressBar=(ProgressBar) findViewById(R.id.pb); mtvProgress=(TextView) findViewById(R.id.tvProgress); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
页面:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btnStartDownload" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始下载" /> <ProgressBar 进度条 android:id="@+id/pb" android:layout_width="match_parent" android:layout_height="wrap_content" style="@android:style/Widget.ProgressBar.Horizontal" android:max="100"/> <TextView 百分比的数字 android:id="@+id/tvProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:text="0%"/> </LinearLayout>