1. 通过Handler 实现线程通信
2. 在主线程中实现Handler的HandlerMessage()方法
3. 在Worker Thread中通过Handler发送消息
Handler,Looper,MessageQuene三者主要完成线程之间的通讯
点击“sendMessage”按钮, 启动线程, 线程休眠2秒, 将TextView里面文字修改
这个例子,实际价值,类似于点击之后,访问服务器,服务器返回一个结果,然后更新在TextView上。
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="first.pack.MainActivity$PlaceholderFragment" > 10 11 <TextView 12 android:id="@+id/firstTextView" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:text="Message" /> 16 17 <Button 18 android:id="@+id/firstButton" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:layout_below="@+id/firstTextView" 22 android:text="sendMessage" /> 23 24 </RelativeLayout>
1 public static class PlaceholderFragment extends Fragment { 2 3 private Button button; 4 private TextView textView; 5 private Handler handler; 6 7 public PlaceholderFragment() { 8 } 9 10 @Override 11 public View onCreateView(LayoutInflater inflater, ViewGroup container, 12 Bundle savedInstanceState) { 13 View rootView = inflater.inflate(R.layout.fragment_main, container, 14 false); 15 16 textView = (TextView)rootView.findViewById(R.id.firstTextView); 17 18 button = (Button)rootView.findViewById(R.id.firstButton); 19 button.setOnClickListener(new ButtonListener()); 20 21 handler = new MyHandler(); //在主线程调用主线程中生成MyHandler,HandlerMessage也是在主线程中执行
22 23 return rootView; 24 } 25 26 class MyHandler extends Handler{ //此方法在主线程调用,因此可以用来修改UI , 从消息队列获取消息来更新 UI 数据 27 28 @Override 29 public void handleMessage(Message msg) { 30 Log.i("tag","NetWork2:" + Thread.currentThread().getName()); // 打印结果显示是主线程!!!!!!!!!!!!!! 31 String s = (String)msg.obj; 32 textView.setText(s); 33 } 34 } 35 36 class ButtonListener implements OnClickListener{ 37 @Override 38 public void onClick(View v) { 39 Thread t = new NetWorkThread(); 40 t.start(); 41 } 42 } 43 44 class NetWorkThread extends Thread{ 45 @Override 46 public void run() { 47 //模拟访问网络,首先休眠2秒 48 try { 49 Thread.sleep(5*1000); 50 } catch (InterruptedException e) { 51 e.printStackTrace(); 52 } 53 //S模拟得到网络的值,要更新到主线程中去, UI只能在主线程中修改, 不能在此Thread修改 54 String s = "Data From Internet"; 55 56 Log.i("tag","NetWork1:" + Thread.currentThread().getName()); //打印结果显示是 Worker Thread 57 58 Message msg = handler.obtainMessage(); 59 msg.obj = s ; //消息是String类型 60 handler.sendMessage(msg); 61 } 62 } 63 }
4秒钟之后
因此,我们看出了的价值
在其他线程中获取数据,进行大量操作,将数据通过Handler发送到MessageQuene中, Looper取出之后Handler在主线程中更新UI !!!!!