当前位置: 首页 > 编程笔记 >

android主线程和子线程之间消息传递详解

周弘盛
2023-03-14
本文向大家介绍android主线程和子线程之间消息传递详解,包括了android主线程和子线程之间消息传递详解的使用技巧和注意事项,需要的朋友参考一下

从主线程发送消息到子线程(准确地说应该是非UI线程)

package com.zhuozhuo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class LooperThreadActivity extends Activity{
 /** Called when the activity is first created. */
 
 private final int MSG_HELLO = 0;
 private Handler mHandler;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  new CustomThread().start();//新建并启动CustomThread实例
  
  findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {//点击界面时发送消息
    String str = "hello";
    Log.d("Test", "MainThread is ready to send msg:" + str);
    mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例
    
   }
  });
  
 }
 
 
 
 
 
 class CustomThread extends Thread {
  @Override
  public void run() {
   //建立消息循环的步骤
   Looper.prepare();//1、初始化Looper
   mHandler = new Handler(){//2、绑定handler到CustomThread实例的Looper对象
    public void handleMessage (Message msg) {//3、定义处理消息的方法
     switch(msg.what) {
     case MSG_HELLO:
      Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);
     }
    }
   };
   Looper.loop();//4、启动消息循环
  }
 }
}

从非UI线程传递消息到UI线程(界面主线程),因为主界面已经有MessageQueue,所以可以直接获取消息处理消息。而上面由主线程向非UI线程中处理消息的时候,非UI线程需要先添加消息队列,然后处理消息循环。

public class ThreadHandlerActivity extends Activity {
 /** Called when the activity is first created. */
 
 private static final int MSG_SUCCESS = 0;//获取图片成功的标识
 private static final int MSG_FAILURE = 1;//获取图片失败的标识
 
 private ImageView mImageView;
 private Button mButton;
 
 private Thread mThread;
 
 private Handler mHandler = new Handler() {
  public void handleMessage (Message msg) {//此方法在ui线程运行
   switch(msg.what) {
   case MSG_SUCCESS:
    mImageView.setImageBitmap((Bitmap) msg.obj);//imageview显示从网络获取到的logo
    Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_success), Toast.LENGTH_LONG).show();
    break;

   case MSG_FAILURE:
    Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_failure), Toast.LENGTH_LONG).show();
    break;
   }
  }
 };
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  mImageView= (ImageView) findViewById(R.id.imageView);//显示图片的ImageView
  mButton = (Button) findViewById(R.id.button);
  mButton.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    if(mThread == null) {
     mThread = new Thread(runnable);
     mThread.start();//线程启动
    }
    else {
     Toast.makeText(getApplication(), getApplication().getString(R.string.thread_started), Toast.LENGTH_LONG).show();
    }
   }
  });
 }
 
 Runnable runnable = new Runnable() {
  
  @Override
  public void run() {//run()在新的线程中运行
   HttpClient hc = new DefaultHttpClient();
   HttpGet hg = new HttpGet("http://csdnimg.cn/www/images/csdnindex_logo.gif");//获取csdn的logo
   final Bitmap bm;
   try {
    HttpResponse hr = hc.execute(hg);
    bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
   } catch (Exception e) {
    mHandler.obtainMessage(MSG_FAILURE).sendToTarget();//获取图片失败
    return;
   }
   mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget();//获取图片成功,向ui线程发送MSG_SUCCESS标识和bitmap对象

//   mImageView.setImageBitmap(bm); //出错!不能在非ui线程操作ui元素

//   mImageView.post(new Runnable() {//另外一种更简洁的发送消息给ui线程的方法。
//    
//    @Override
//    public void run() {//run()方法会在ui线程执行
//     mImageView.setImageBitmap(bm);
//    }
//   });
  }
 };

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Android主线程和子线程区别详解,包括了Android主线程和子线程区别详解的使用技巧和注意事项,需要的朋友参考一下 主线程和子线程的区别 每个线程都有一个唯一标示符,来区分线程中的主次关系的说法。 线程唯一标示符:Thread.CurrentThread.ManagedThreadID; UI界面和Main函数均为主线程。 被Thread包含的“方法体”或者“委托”均为子线程。

  • 本文向大家介绍wxpython多线程防假死与线程间传递消息实例详解,包括了wxpython多线程防假死与线程间传递消息实例详解的使用技巧和注意事项,需要的朋友参考一下 wxpython中启用线程的方法,将GUI和功能的执行分开。 网上关于python多线程防假死与线程传递消息是几年前的,这里由于wxpython和threading模块已经更新最新,因此给出最新修改代码,能在2017年最新版的pyt

  • 我是android和java中多线程的新手,我很难实现一个简单的模型,在这个模型中,我们可以启动工作线程,并从主线程向工作线程发送一些消息或runnable,它在主线程中执行一些操作,并将结果发送给主线程并更新ui线程 我试过这个: 主要活动:

  • 消息传递 稍加考虑,上一节的练习题其实是不完整的,它只是评分系统中的一环,一个评分系统是需要先把信息从数据库或文件中读取出来,然后才是评分,最后还需要把评分结果再保存到数据库或文件中去。如果一步一步串行地做这三个步骤,是完全没有问题的。那么我们是否可以用三个线程来分别做这三个步骤呢?上一节练习题我们已经用了一个线程来实现评分,那么我们是否也可以再用一个线程来读取成绩,再用另个线程来实现保存呢? 如

  • 我的程序中运行了两个线程。当我尝试在非主线程中使用OpenGL函数时,它抛出了一个IllegalStateException:当前线程中没有当前的OpenGL上下文。所以我的问题是,如何将上下文从主线程传递到另一个线程?我正在使用LWJGL 3。

  • 问题内容: 我相信主线程不能在子线程之前死亡。但是有什么办法可以检查吗?我在下面写了一个简单的程序。有人能证明它几乎把理论放在一边吗? 经过詹姆斯的建议。我尝试了以下程序。 问题答案: 从http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html: Java虚拟机将继续执行线程,直到发生以下任何一种情况: 已调用类Runtime的退

  • 我在编写一个应用程序时遇到了一些问题。它的工作是用线来解决迷宫。一个线程开始,对于每个分支,它调用另一个类中的静态方法,传递另一个线程需要的参数,然后为每个路径启动线程。我的输出都搞乱了,我不确定这是多线程问题还是引用的问题。下面是一些代码(每个线程都有一个类的新实例): 和返回ValidPaths的方法 CheckEnvirondings使用传递给子级的深度副本(通过构造函数)来验证子级可以采用

  • 本文向大家介绍详解C#多线程之线程同步,包括了详解C#多线程之线程同步的使用技巧和注意事项,需要的朋友参考一下 多线程内容大致分两部分,其一是异步操作,可通过专用,线程池,Task,Parallel,PLINQ等,而这里又涉及工作线程与IO线程;其二是线程同步问题,鄙人现在学习与探究的是线程同步问题。 通过学习《CLR via C#》里面的内容,对线程同步形成了脉络较清晰的体系结构,在多线程中实现