您的位置:首页 > 产品设计 > UI/UE

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

2014-06-23 15:22 465 查看
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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: