![]()
1 /**android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个MessageQueue(消息队列),
2 * 但是MessageQueue被封装到Looper里面了。
3 *
4 * Looper
5 *
6 * Looper 循环着。被设计用来使一个普通线程变成Looper线程。
7 * Looper.prepare()将当前线程初始化为Looper线程
8 * ....实例化Handler,处理消息
9 * Looper.loop()开始循环处理消息队列。调用后开始不断从Looper内部的消息队列中取出消息执行
10 *
11 * 注意:Looper.loop()之后的方法不会再执行到。一个Thread只能有一个Looper对象
12 * Looper类还有一些方法:Looper.myLooper()得到当前线程looper对象
13 * Looper.getThread()得到looper对象所属线程
14 * Looper.quit()结束looper循环
15 *
16 *
17 * Handler
18 *
19 * Handler扮演了往MessageQueue上添加消息和处理消息的角色(只处理由自己发出的消息)。
20 * 即通知MessageQueue它要执行一个任务(sendMessage),并在循环到自己的时候执行该任务(handleMessage),整个过程是异步的。
21 * Handler创建时会关联一个Looper,默认构造方法将关联当前线程的looper.
22 *
23 * 一个线程可以有多个Handler,但只能有一个Looper.
24 *
25 *拿到handler引用之后,我们就可以使用它的方法。比如:
26 * post(Runnable) //其实post发出的Runnable对象最后都被封装成Message对象了
27 * postAtTime(Runnable,long)
28 * postDelayed(Runnable,long)
29 * sendEmptyMessage(int)
30 * sendMessage(Message)
31 * sendMessageAtTime(Message,long)
32 * sendMessageDelayed(Message,long)
33 *
34 *
35 * Message类
36 * Message被存放在MessageQueue中,一个MessageQueue中可以包含多个Message对象。
37 * Message中包含两个额外的int字段和一个Object字段。
38 * Message.arg1 /Message.arg2 存放整形数据
39 * Message.obj 存放发送给接收器的Object类型的任意对象
40 * Message.what 用来指定用户自定义的消息代码
41 *
42 * 使用Message.obtain()或Handler.obtainMessage()函数来获取Message对象
43 *
44 *
45 * 异步消息处理的流程:
46 * 首先需要在主线程当中创建一个Handler对象,并重写handlerMessage()方法。
47 * 然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。
48 * 之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理的消息,
49 * 最后分发回Handler的handlerMessage()方法中。
50 * 由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,所以可以安心在这里更新UI
51 *
52 *
53 *
54 */
55
56
57 public class MainActivity extends AppCompatActivity {
58
59 ViewPager viewPager;
60 Button btn_start;
61 List<Fragment> mList = new ArrayList<>();
62
63 Handler mainHandler, childHandler;
64
65 @Override
66 protected void onCreate(Bundle savedInstanceState) {
67 super.onCreate(savedInstanceState);
68 setContentView(R.layout.activity_main);
69 initView();
70
71
72 }
73
74 private void initView() {
75 viewPager = (ViewPager) findViewById(R.id.viewpager);
76 btn_start = (Button) findViewById(R.id.btn_start);
77
78 initData();
79
80 FragmentManager fm = getSupportFragmentManager();
81 //如果使用PagerAdapter,需要重写instantiateItem()加载视图,onDestroy()销毁视图
82 //FragmentPagerAdapter,每一个生成的Fargment都保存在内存中,也就是FragmentManaer中,就算刷新Adapter,还是使用的上次缓存的Fragment
83 //FragmentStatePagerAdapter的instantiateItem()加载视图的时候会每次重新创建Fragment。
84 viewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
85 @Override
86 public Fragment getItem(int position) {
87 return mList.get(position%6);
88 }
89
90 @Override
91 public int getCount() {
92 return Integer.MAX_VALUE;
93 }
94 });
95 viewPager.setCurrentItem(0);
96
97 //主线程接收子线程消息并处理
98 mainHandler = new Handler() {
99 @Override
100 public void handleMessage(Message msg) {
101 super.handleMessage(msg);
102 Log.e("TAG", "最终处理" + (int) msg.obj);
103 viewPager.setCurrentItem((int) msg.obj);
104
105 if (childHandler != null) {
106 Message toChild = childHandler.obtainMessage();
107 toChild.obj = msg.obj;
108 childHandler.sendMessageDelayed(toChild, 500);
109 }
110 }
111 };
112
113 new myThread().start();
114
115 //点击开始轮播图片
116 btn_start.setOnClickListener(new View.OnClickListener() {
117 @Override
118 public void onClick(View v) {
119 if (childHandler != null) {
120 Message firstMsg = childHandler.obtainMessage();
121 firstMsg.obj = viewPager.getCurrentItem();
122 childHandler.sendMessageDelayed(firstMsg, 500);
123 }
124 }
125 });
126
127 }
128
129 class myThread extends Thread {
130
131 @Override
132 public void run() {
133 Looper.prepare();//初始化消息队列,必须在创建Handler之前
134 Log.e("TAG", "************");
135
136 childHandler = new Handler() {
137 @Override
138 public void handleMessage(Message msg) {
139 Message toMain = mainHandler.obtainMessage();
140 toMain.obj = (int)msg.obj + 1;
141 Log.e("TAG", "toMain obj " + (int) (toMain.obj));
142 mainHandler.sendMessageDelayed(toMain, 500);
143 }
144 };
145
146 //启动子线程消息队列
147 Looper.loop();
148
149 }
150 }
151
152
153
154 @Override
155 protected void onDestroy() {
156 Log.e("TAG","@@@@@@@@@@@@@@@@@onDestroy");
157 childHandler.getLooper().quit();
158 super.onDestroy();
159 }
160
161 private void initData() {
162 mList.add(new OneFragment());
163 mList.add(new TwoFragment());
164 mList.add(new ThreeFragment());
165 mList.add(new FourFragment());
166 mList.add(new FiveFragment());
167 mList.add(new SixFragment());
168 }
169 }
MainActivity.java