handler/ runOnUiThread /AsyncTask


在J2ME中,多线程的处理是很简单的,似乎并不用考虑很多问题,顶多是同步方面很让人头疼,而在Android中,一切似乎不那么明了了,很重要的一点是在其他线程中是不能直接访问主UI线程成员的。比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的,在C#中也是这样,可能是为了主线程的安全吧。

在J2ME中,多线程的处理是很简单的,似乎并不用考虑很多问题,顶多是同步方面很让人头疼,而在Android中,一切似乎不那么明了了,很重要的一点是在其他线程中是不能直接访问主UI线程成员的。比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的,在C#中也是这样,可能是为了主线程的安全吧。
对于此类情况,Android提供了一些间接访问的方法。

1.runOnUiThread函数
这个函数是Activity的成员函数,格式是public final void runOnUiThread (Runnable action)
在自定义线程中执行对应Activity的runOnUiThread函数就好了,但是很明显,参数还是个线程,这个

函数基本上没什么意义。

这里需要注意的是runOnUiThread是Activity中的方法,在线程中我们需要告诉系统是哪个activity调用,所以前面显示的指明了activity。

activity.this. runOnUiThread(new Runnable() { 
                    @Override 
                        public void run() { 

                           // refresh ui 的操作代码

                        } 
                    });

2.Handler
这应该是Android多线程中用的最多的工具了,这里Android借鉴了Windows的消息机制,不同线程之间可以用消息进行交流。除了主线程(UI线程)外,通过继承Thread或Runnable生成的线程是不包含消息循环(Looper)的。因此必须在线程中调用Looper.prepare()准备一个消息循环,调用Looper.loop()开始循环,就像是这样:
class LooperThread extends Thread {
      public Handler mHandler;
      public void run() {
          Looper.prepare();
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          Looper.loop();
      }
}
这其中Handler是用来接受并处理消息的,如果像上面写的那样调用无参数构造函数生成handler,这个Handler对应的就是所在线程,也可以用Looper做参数,这样生成的Handler对应的是Looper所在的线程。可以通过Looper.myLooper()获取当前线程的Looper。调用Handler对象的sendMessage(Message)函数可以向对应线程发送消息。

还可以用post(runnable)  来传递一个线程对象。  免去了在looper中解析message的过程。。
例:
public class ThreadMain extends Activity {
    /** Called when the activity is first created. */
private final static int MSG_BEGIN=1;
private final static int MSG_END=2;
    private ProgressDialog dialog=null;
    private Button bt=null;
    private Handler handle=new Handler(){
    public void handleMessage(Message msg){
       switch(msg.what){
       case MSG_BEGIN:
        showProgress();
        break;
        
       case MSG_END:
        dismissProgress();
        alertDialog();
        break;
       }
       super.handleMessage(msg);
    }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bt=(Button)findViewById(R.id.bt);
        bt.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
     // TODO Auto-generated method stub
     doThread();
    }});
    }
    
    private void doThread(){
    new Thread(){
       public void run(){
        try{
         sendMsg(MSG_BEGIN);
         Thread.sleep(4000);
         sendMsg(MSG_END);
        }catch(Exception e){
         e.printStackTrace();
        }
       }
    }.start();
    }
    
    private void sendMsg(int m){
    Message msg=new Message();
    msg.what=m;
    handle.sendMessage(msg);
    }
    
    private void showProgress(){
    dialog=ProgressDialog.show(this, "", "正在……", false);
    }
    
    private void dismissProgress(){
    dialog.dismiss();
    }
    
    private void alertDialog(){
    new AlertDialog.Builder(ThreadMain.this).setMessage("完成操作")
    .setNegativeButton("确定", new DialogInterface.OnClickListener(){
    @Override
    public void onClick(DialogInterface dialog, int which) {
     // TODO Auto-generated method stub
    }}).show();
    }
}

3.后台异步任务:
Adnroid的AsyncTask类实现了后台任务的处理,即那些通过“ 提交信息->后台处理->返回结果”步骤完成的任务。
例:
class PageTask extends AsyncTask<String, Integer, String> { 

        /* 对应类型AsyncTask< doInBackground函数参数类型 , onProgressUpdate函数参数类型 , doInBackground函数返回结果类型>
       */

        @Override 
        protected String doInBackground(String... params) {
/*后台函数,可以放心的调用主线程的成员,params是不定参数 , 取决于执行时的输入,可以用params[0]、params[1]等方式引用*/
            return null; 
        } 
        @Override 
        protected void onCancelled() { 
            super.onCancelled(); 
        } 
        @Override 
        protected void onPostExecute(String result) { 
            // 返回结果,result为doInBackground的返回值
            message.setText(result); 
        } 
        @Override 
        protected void onPreExecute() { 
            // 任务启动,可以在这里显示一个对话框,这里简单处理 
            message.setText(R.string.task_started); 
        } 
        @Override 
        protected void onProgressUpdate(Integer... values) { 
            // 更新进度 
            message.setText(values[0]); 
        } 
    }


启动方式:
PageTask task = new PageTask(); 
task.execute(str1,str2);

于此类情况,Android提供了一些间接访问的方法。

1.runOnUiThread函数
这个函数是Activity的成员函数,格式是public final void runOnUiThread (Runnable action)
在自定义线程中执行对应Activity的runOnUiThread函数就好了,但是很明显,参数还是个线程,这个

函数基本上没什么意义。

这里需要注意的是runOnUiThread是Activity中的方法,在线程中我们需要告诉系统是哪个activity调用,所以前面显示的指明了activity。

activity.this. runOnUiThread(new Runnable() { 
                    @Override 
                        public void run() { 

                           // refresh ui 的操作代码

                        } 
                    });

2.Handler
这应该是Android多线程中用的最多的工具了,这里Android借鉴了Windows的消息机制,不同线程之间可以用消息进行交流。除了主线程(UI线程)外,通过继承Thread或Runnable生成的线程是不包含消息循环(Looper)的。因此必须在线程中调用Looper.prepare()准备一个消息循环,调用Looper.loop()开始循环,就像是这样:
class LooperThread extends Thread {
      public Handler mHandler;
      public void run() {
          Looper.prepare();
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          Looper.loop();
      }
}
这其中Handler是用来接受并处理消息的,如果像上面写的那样调用无参数构造函数生成handler,这个Handler对应的就是所在线程,也可以用Looper做参数,这样生成的Handler对应的是Looper所在的线程。可以通过Looper.myLooper()获取当前线程的Looper。调用Handler对象的sendMessage(Message)函数可以向对应线程发送消息。
例:
public class ThreadMain extends Activity {
    /** Called when the activity is first created. */
private final static int MSG_BEGIN=1;
private final static int MSG_END=2;
    private ProgressDialog dialog=null;
    private Button bt=null;
    private Handler handle=new Handler(){
    public void handleMessage(Message msg){
       switch(msg.what){
       case MSG_BEGIN:
        showProgress();
        break;
        
       case MSG_END:
        dismissProgress();
        alertDialog();
        break;
       }
       super.handleMessage(msg);
    }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bt=(Button)findViewById(R.id.bt);
        bt.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
     // TODO Auto-generated method stub
     doThread();
    }});
    }
    
    private void doThread(){
    new Thread(){
       public void run(){
        try{
         sendMsg(MSG_BEGIN);
         Thread.sleep(4000);
         sendMsg(MSG_END);
        }catch(Exception e){
         e.printStackTrace();
        }
       }
    }.start();
    }
    
    private void sendMsg(int m){
    Message msg=new Message();
    msg.what=m;
    handle.sendMessage(msg);
    }
    
    private void showProgress(){
    dialog=ProgressDialog.show(this, "", "正在……", false);
    }
    
    private void dismissProgress(){
    dialog.dismiss();
    }
    
    private void alertDialog(){
    new AlertDialog.Builder(ThreadMain.this).setMessage("完成操作")
    .setNegativeButton("确定", new DialogInterface.OnClickListener(){
    @Override
    public void onClick(DialogInterface dialog, int which) {
     // TODO Auto-generated method stub
    }}).show();
    }
}

3.后台异步任务:
Adnroid的AsyncTask类实现了后台任务的处理,即那些通过“ 提交信息->后台处理->返回结果”步骤完成的任务。
例:
class PageTask extends AsyncTask<String, Integer, String> { 

        /* 对应类型AsyncTask< doInBackground函数参数类型 , onProgressUpdate函数参数类型 , doInBackground函数返回结果类型>
       */

        @Override 
        protected String doInBackground(String... params) {
/*后台函数,可以放心的调用主线程的成员,params是不定参数 , 取决于执行时的输入,可以用params[0]、params[1]等方式引用*/
            return null; 
        } 
        @Override 
        protected void onCancelled() { 
            super.onCancelled(); 
        } 
        @Override 
        protected void onPostExecute(String result) { 
            // 返回结果,result为doInBackground的返回值
            message.setText(result); 
        } 
        @Override 
        protected void onPreExecute() { 
            // 任务启动,可以在这里显示一个对话框,这里简单处理 
            message.setText(R.string.task_started); 
        } 
        @Override 
        protected void onProgressUpdate(Integer... values) { 
            // 更新进度 
            message.setText(values[0]); 
        } 
    }


启动方式:
PageTask task = new PageTask(); 
task.execute(str1,str2);

在J2ME中,多线程的处理是很简单的,似乎并不用考虑很多问题,顶多是同步方面很让人头疼,而在Android中,一切似乎不那么明了了,很重要的一点是在其他线程中是不能直接访问主UI线程成员的。比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的,在C#中也是这样,可能是为了主线程的安全吧。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值