Android后台线程和UI线程的5种交互

5种方式:

1、使用 Activity.runOnUiThread(new Runnable(){

 public void run(){ }

  });

2、使用view.post(new Runnable(){

 public void run(){ }

  });

3、使用view.postDelay(new Runnable(){

    public void run(){ }

 },2000);

4、使用handler

5、使用AsyncTask


其中前三种可以在后台线程中直接调用来更新UI线程的控件;

第四种:通过在后台线程中发送消息,然后在handler的处理函数中更新UI控件;

第五种:可以传入控件,然后覆盖AsyncTask的函数,对控件进行更新。


实例如下:

public class TestActivity extends Activity implements OnClickListener{  
	private static final String TAG = TestActivity.class.getSimpleName();
	private String urlStr = "";
	private int ctrl_num =5;
	private LinearLayout layout;
	private LayoutParams layoutParams;
	private Button btnAttr[];
	private ImageView imageView;
	private Bitmap bitmap;
	
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		initLayout();
		setContentView(layout);
		initCtrl();
	}

	//动态创建布局
	private void initLayout(){
		layout = new LinearLayout(this);
		layout.setOrientation(LinearLayout.HORIZONTAL);
	}
	
	//动态创建控件
	private void initCtrl(){
		layoutParams = new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
		btnAttr = new Button[ctrl_num];
		for(int i=0;i<ctrl_num;i++){
			btnAttr[i] = new Button(this);
			btnAttr[i].setId(1000+i);
			btnAttr[i].setText("测试"+i+1);
			layout.addView(btnAttr[i],layoutParams);
			btnAttr[i].setOnClickListener(this);
		}
		
		imageView = new ImageView(this);
	    layout.addView(imageView, layoutParams);
		
	}
	
	//点击事件
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
			case 1000:
				MyThread myThread = new MyThread();
				myThread.start();
				break;
				
			case 1001:
				break;
				
			case 1002:
				break;
				
			case 1003:
				break;
				
			case 1004:
				useAsyncTask(urlStr);
				break;
				
			default:
				break;	
		}
	}
	
	
	//方法1:通过activity的runOnUiThread直接在线程中更新控件
	private void useRunOnUiThread(){
		runOnUiThread(new Runnable(){
			@Override
			public void run() {
				if(null != bitmap){
					btnAttr[0].setText("结束1");
					imageView.setBackgroundColor(Color.BLACK);
					imageView.setImageBitmap(bitmap);
				}
				
			}
		});
	}
	
	//方法2:通过控件view的post方法直接在线程中更新控件
	private void useViewPost(){
		btnAttr[0].post(new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if(null != bitmap){
					btnAttr[1].setText("结束2");
					imageView.setBackgroundColor(Color.BLACK);
					imageView.setImageBitmap(bitmap);
				}
			}
		});
	}
	
	//方法3:通过控件view的postDelay方法直接在线程中更新控件
	private void useViewPostDelay(){
		btnAttr[0].postDelayed(new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if(null != bitmap){
					btnAttr[2].setText("结束3");
					imageView.setBackgroundColor(Color.BLACK);
					imageView.setImageBitmap(bitmap);
				}
			}
		}, 2000);
	}	
	
	//方法4:通过handler;线程下载结束后,发送消息,在handler中更新控件
	private void useHander(){
		Message msg = handler.obtainMessage();
		msg.what = 0;
		handler.sendMessage(msg);
	}
	
	private Handler handler = new Handler(){
		public void handleMessage(Message msg){
			if(0 == msg.what){
				btnAttr[3].setText("结束4");
				imageView.setBackgroundColor(Color.BLACK);
				imageView.setImageBitmap(bitmap);
			}
		}
	};
	
	//方法5:使用AsyncTask<Params, Progress, Result>
	private void useAsyncTask(final String urlStr){
		MyTask myTask = new MyTask();
		myTask.execute(urlStr);
	}
	
	//AsyncTask的三个参数:
	//Params 启动任务执行的输入参数,
	//Progress 后台任务执行的百分比
	//Result 后台执行任务最终返回的结果
	private class MyTask extends AsyncTask<String,Integer,Bitmap>{
		//在ui线程中执行,可以访问ui控件,在doInBackground之前执行
		protected void onPreExecute(){
			Log.i(TAG,"onPreExecute");
			super.onPreExecute();
		}
		
		//在ui线程中执行,可以访问ui控件,在doInBackground之后执行;
		//自动调用,Bitmap result为doInBackground执行的结果,可以使用
		//Bitmap result对ui控件进行更新
		protected void onPostExecute(Bitmap result){
			Log.i(TAG,"onPostExecute");
			super.onPostExecute(result);
			btnAttr[4].setText("结束5");
			imageView.setBackgroundColor(Color.BLACK);
			imageView.setImageBitmap(bitmap);
		}
		
		//刷新进度条,执行publishProgress后,会自动调用onProgressUpdate,在ui线程中执行
		protected void onProgressUpdate(Integer... values){
			Log.i(TAG,"onProgressUpdate");
			super.onProgressUpdate(values);
		}
		
		@Override
		protected Bitmap doInBackground(String... params) {
			Log.i(TAG,"doInBackground");
			publishProgress(100);
			return downloadImage(params[0]);
		}
	}
	
	//线程类
	private class MyThread extends Thread{
		public void run(){
			bitmap = downloadImage(urlStr);
			if(null != bitmap){
				//
				useRunOnUiThread();
				
				//
				useViewPost();
				
				//
				useViewPostDelay();
				
				//
				useHander();
			}
			
		}
	}
	
	//下载文件
	private Bitmap downloadImage(String urlStr){
		Bitmap bitmap = null;
		if(null == urlStr){
			return bitmap;
		}
		//
		try {
			URL url = new URL(urlStr);
			InputStream is = url.openStream();
			bitmap = BitmapFactory.decodeStream(is);
			if(null != bitmap){
				return bitmap;
			}
		} 
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return bitmap;
	}
	
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值