源地址:http://www.apkbus.com/android-13434-1-1.html
Android开发中在程序之间通讯的接口做的还是非常丰富的本例主要向大家介绍程序之间是如何进行沟通,有哪几种沟通方式如何来实现沟通。
1.使用handler传递消息
handler 大家可以把它想象成主线程(UI线程)的一个子线程,它可以给主线程(UI线程)发送数据从而更新主线程(UI线程)的UI与逻辑,handler是一个子线程所以它的耗时操作不会阻塞主线程,大家都知道在android的开发中如果代码中某个地方阻塞主线程超过5秒的话系统会提示ANR (系统提示强制关闭)所以在耗时操作上我们可以考虑开启一个子线程避免ANR。 handler会向主线程发送消息会以队列的形式排列着配合等待主线程更新UI逻辑等等。
下面这个例子诠释了这一点利用handler传递消息来更新主线程的UI显示内容点击按钮后每过一秒通过handler发送消息更新UI线程显示的时间直到显示时间更新到10然后结束这个线程。
1. public class HandlerActivity extends Activity implements Runnable{
2.
3. /**更新时间**/
4. public final static int UPDATE_TIME =0;
5. /**更新时间成功**/
6. public final static int UPDATE_COMPLETED =1;
7.
8. /**记录显示时间 超过10秒结束线程**/
9. private int mShowNumber = 0;
10.
11. /**开始计时按钮**/
12. private Button mButton = null;
13.
14. /**计时显示内容**/
15. private TextView mTextView = null;
16.
17. /**线程**/
18. private Thread mThread = null;
19.
20. /**线程关闭的标志**/
21. private boolean mRunning = false;
22.
23. Handler handler = new Handler() {
24. @Override
25. public void handleMessage(Message msg) {
26.
27. Bundle bundle= msg.getData();
28. //通过key的名称拿到它的值
29. String number = bundle.getString("number");
30. //msg.what为handler接收到的消息编号
31. switch(msg.what) {
32. case UPDATE_TIME:
33. mTextView.setText("正在更新时间" + number);
34. break;
35. case UPDATE_COMPLETED:
36. mTextView.setText("更新完毕");
37. break;
38. }
39. super.handleMessage(msg);
40. }
41. };
42.
43. @Override
44. protected void onCreate(Bundle savedInstanceState) {
45. setContentView(R.layout.handler);
46.
47. /**拿到button 与 TextView 对象**/
48. mButton = (Button)findViewById(R.id.button0);
49. mTextView = (TextView)findViewById(R.id.textView0);
50. mThread = new Thread(this);
51.
52. mButton.setOnClickListener(new OnClickListener() {
53. @Override
54. public void onClick(View arg0) {
55. /**点击按钮后开始线程开始计时**/
56. mRunning = true;
57. mThread.start();
58. }
59. });
60.
61. mTextView.setText("点击按钮开始更新时间");
62. super.onCreate(savedInstanceState);
63. }
64.
65. public void ShowDialog(String string) {
66. AlertDialog.Builder builder = new AlertDialog.Builder(
67. HandlerActivity.this);
68. builder.setIcon(R.drawable.icon);
69. builder.setTitle(string);
70. builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
71. public void onClick(DialogInterface dialog, int whichButton) {
72. finish();
73. }
74. });
75. builder.show();
76. }
77.
78.
79.
80. @Override
81. public void run() {
82.
83. while (mRunning) {
84. try {
85. mShowNumber++;
86. /** 把须要的数据放入bandle中 **/
87. Bundle bandle = new Bundle();
88. bandle.putString("number", String.valueOf(mShowNumber));
89.
90. /** 设置这条信息的编号为更新时间 **/
91. /** 将bandle写入message中 **/
92. /** 最后将这个message发送出去 **/
93. /** mShowNumber小于10更新时间 否则更新完毕 **/
94. Message msg = new Message();
95. if(mShowNumber <=10) {
96. msg.what = UPDATE_TIME;
97. }else {
98. mRunning = false;
99. msg.what = UPDATE_COMPLETED;
100. }
101. msg.setData(bandle);
102. handler.sendMessage(msg);
103. Thread.sleep(1000);
104. } catch (InterruptedException e) {
105. e.printStackTrace();
106. }
107. }
108. }
109. }
2.Notifation 通知栏信息
Notifation 通知栏会在屏幕上方向用户提示信息 但是不会打断用户正在阅读的内容,除非用户手动将 Notifation 通知栏拉下。 Notifation 的好处就是在于不会影响用户的操作,比如用户正在阅读非常重要的信息这时候帮他直接打开一个 activity 会非常不合适 因为直接影响到了他当时的操作行为 所以 Notifation 就出来了。建议大家在开发中遇到可能打断用户使用的情况下都去使用 Notifation 通知栏。
屏幕上方为弹出的 Notifation 通知栏
将Notifation通知栏拉下后会出现相应的信息
1. public class NotificationActivity extends Activity {
2. NotificationManager mManager = null;
3. Notification notification =null;
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. setContentView(R.layout.notification);
7.
8. // 得到通知消息的管理器对象,负责管理 Notification 的发送与清除消息等
9. mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
10. // 创建Notification对象 参数分别代表 通知栏 中显示的图标 显示的标题 显示的时间
11. notification = new Notification(R.drawable.jay,
12. "Android专业开发群", System.currentTimeMillis());
13.
14. // 设置在通知栏中点击后Notification自动消失
15. notification.flags = Notification.FLAG_AUTO_CANCEL;
16.
17. //设置点击后转跳的新activity
18. Intent intent = new Intent(this, MyShowActivity.class);
19. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
20.
21. //通过bundle可以带一些数据过去 这里将字符串传递了过去
22. Bundle bundle = new Bundle();
23. bundle.putString("name", "从Notification转跳过来的");
24. intent.putExtras(bundle);
25.
26. //设置通知栏中显示的内容
27. PendingIntent contentIntent = PendingIntent.getActivity(this,
28. R.string.app_name, intent, PendingIntent.FLAG_UPDATE_CURRENT);
29. notification.setLatestEventInfo(this, "Android专业开发群",
30. "QQ群号 164257885", contentIntent);
31.
32.
33. Button button0 = (Button)findViewById(R.id.button0);
34. button0.setOnClickListener(new OnClickListener() {
35.
36. @Override
37. public void onClick(View arg0) {
38. //打开这个Notification通知
39. mManager.notify(0, notification);
40. }
41. });
42.
43. Button button1 = (Button)findViewById(R.id.button1);
44. button1.setOnClickListener(new OnClickListener() {
45.
46. @Override
47. public void onClick(View arg0) {
48. //关闭这个Notification通知
49. mManager.cancelAll();
50. }
51. });
52.
53. super.onCreate(savedInstanceState);
54. }
55.
56. }
3.广播的发送与接收
Android开发中如果须要对两个完全没关系的程序之间进行通信就可以使用发送广播与接收广播的机制来实现,例如程序A发送了一个广播程序B接受到做一些事情这样就达到了相互的通讯。
调用sendBroadcast()传入intent 后来发送广播
1. public class BroadcastActivity extends Activity {
2.
3.
4.
5. Button mButton0 = null;
6. Button mButton1 = null;
7.
8. @Override
9. protected void onCreate(Bundle savedInstanceState) {
10. setContentView(R.layout.broadcast);
11.
12. mButton0 = (Button)findViewById(R.id.button0);
13. mButton0.setOnClickListener(new OnClickListener() {
14.
15. @Override
16. public void onClick(View arg0) {
17. Intent intent = new Intent(MyService.SEND_OK_MESSAGE);
18. intent.putExtra("name", "您发送了OK这条广播哦");
19. sendBroadcast(intent);
20. }
21. });
22.
23. mButton1 = (Button)findViewById(R.id.button1);
24. mButton1.setOnClickListener(new OnClickListener() {
25.
26. @Override
27. public void onClick(View arg0) {
28. Intent intent = new Intent(MyService.SEND_CANCLE_MESSAGE);
29. intent.putExtra("name", "您发送了Cancle这条广播哦");
30. sendBroadcast(intent);
31. }
32. });
33.
34. //启动Service
35. Intent i = new Intent(this, MyService.class);
36. startService(i);
37. super.onCreate(savedInstanceState);
38. }
39. }
接收广播的话我们开启一个service在service中通过BroadcastReceiver来接收广播前提是须要接收的广播须要在onStart()中注册一下在AndroidManifest.xml中可以过滤只接收须要接收的广播、
<service android:name=".MyService">
2. <intent-filter>
3. <action android:name="cn.m15.xys.MyService"></action>
4. </intent-filter>
5. <intent-filter>
6. <action android:name="send.ok.message" />
7. <action android:name="send.cancle.message" />
8. </intent-filter>
9. </service>
在onStart()中注册了程序中所需要的两个广播
1. public class MyService extends Service {
2.
3. public final static String SEND_OK_MESSAGE = "send.ok.message";
4. public final static String SEND_CANCLE_MESSAGE = "send.cancle.message";
5.
6. private BroadcastReceiver myBroadCast = new BroadcastReceiver() {
7.
8. @Override
9. public void onReceive(Context context, Intent intent) {
10. String action = intent.getAction();
11. if (action.equals(SEND_OK_MESSAGE)) {
12. Toast.makeText(context, "接收到了一条广播为" + SEND_OK_MESSAGE, Toast.LENGTH_LONG).show();
13. }else if(action.equals(SEND_CANCLE_MESSAGE)) {
14. Toast.makeText(context, "接收到了一条广播为" + SEND_CANCLE_MESSAGE, Toast.LENGTH_LONG).show();
15. }
16. }
17.
18. };
19.
20. @Override
21. public void onCreate() {
22. super.onCreate();
23. }
24.
25. @Override
26. public void onStart(Intent intent, int startId) {
27. //注册这两个广播
28. IntentFilter myFilter = new IntentFilter();
29. myFilter.addAction(SEND_OK_MESSAGE);
30. myFilter.addAction(SEND_CANCLE_MESSAGE);
31. this.registerReceiver(myBroadCast, myFilter);
32. super.onStart(intent, startId);
33. }
34. @Override
35. public IBinder onBind(Intent arg0) {
36. return null;
37. }
38.
39. }
这里注意一下 service如果没有起来我们是接收不到广播的所以一定要保证接收的时候service是开启的,上例中的service是在打开activity时开启的但是如果用户把手机关掉然后在开机,这样的话service就不是打开状态这样就非常危险了因为这时scrvice就接收不到任何消息了除非用户再次进activity才会帮他打开scrvice所以我们可以在用户开机后就直接将scrvice打开,具体的实现方式如下
在AndroidManifest.xml中注册一个开机广播 这个广播系统只会在开机发出而且只会发出一次所以我们接收这个广播就可以知道手机是否为开机状态
1. <receiver android:name=".MyBootReceiver" >
2. <intent-filter>
3. <action android:name="android.intent.action.BOOT_COMPLETED" />
4. </intent-filter>
5. </receiver>
注意加入权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
在BroadcastRecevier中接收开机广播 然后打开service就可以实现开机启动service。
1. public class MyBootReceiver extends BroadcastReceiver {
2. /**开机广播**/
3. static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
4.
5. @Override
6. public void onReceive(Context context, Intent intent) {
7. /**如果为开机广播则开启service**/
8. if (intent.getAction().equals(BOOT_COMPLETED)) {
9. Intent i = new Intent(context, MyService.class);
10. context.startService(i);
11. }
12.
13. }
14. }
3.Activity 与 Activity 之间的转跳
在软件应用的开发中肯定会有多个 Activity 这样它们之间就会存在相互转跳的关系 转跳的实现方式还是使用 Intent 然后 startActivity ,当然转跳的话是可以带数据过去的。比如从 A 跳到 B 可以把 A 中的一些数据通过 Intent 传递给 B 。
读下面这段代码大家会发现intent与bandle传递数值的方式基本一样为什么还要分成两个呢?确实他们两个传递的数值的方式非常类似,他们两个的区别就是Intent属于把零散的数据传递过去而bundle则是把零散的数据先放入bundle然后在传递过去。我举一个例子比如我们现在有3个activity A.B.C 须要把A的数据穿给B然后在穿给C,如果使用intent一个一个传递须要在A类中一个一个传递给B然后B类中获取到所有数值 然后在一个一个传递给C 这样很麻烦但是如果是bundle的话 B类中直接将bundler传递给C不用一个一个获得具体的值 然后在C类中直接取得解析数值。
传递
/**Activity之间传递值**/
2. Button botton3 = (Button)findViewById(R.id.button3);
3. botton3.setOnClickListener(new OnClickListener() {
4.
5. @Override
6. public void onClick(View arg0) {
7. Intent intent = new Intent(mContext,ShowActivity.class);
8. //使用intent.putExtra()直接传递
9. intent.putExtra("name", "雨松MOMO");
10. intent.putExtra("age", 25);
11. intent.putExtra("boy", true);
12.
13. //把数值放进bundle 然后在把整个bundle通过intent.putExtra()传递
14. Bundle bundle = new Bundle();
15. bundle.putString("b_name", "小可爱");
16. bundle.putInt("b_age", 23);
17. bundle.putBoolean("b_boy", false);
18. //在这里把整个bundle 放进intent中
19. intent.putExtras(bundle);
20. //开启一个新的 activity 将intent传递过去
21. startActivity(intent);
22. }
23. });
接收
1. public class ShowActivity extends Activity {
2.
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. setContentView(R.layout.my);
6.
7. Intent intent = getIntent();
8.
9. String name = intent.getStringExtra("name");
10. //第二个参数为默认值 意思就是如果在intent中拿不到的话
11. //就用默认值
12. int age = intent.getIntExtra("age", 0);
13. boolean isboy = intent.getBooleanExtra("boy", false);
14. TextView textView0 = (TextView)findViewById(R.id.text0);
15.
16. textView0.setText("姓名 " + name + "年龄 " + age + "男孩? " + isboy);
17.
18.
19. Bundle bundle = intent.getExtras();
20. name = bundle.getString("b_name");
21. //第二个参数为默认值 意思就是如果在bundle中拿不到的话
22. //就用默认值
23. age = bundle.getInt("b_age",0);
24. isboy = bundle.getBoolean("b_boy", false);
25.
26. TextView textView1 = (TextView)findViewById(R.id.text1);
27.
28. textView1.setText("姓名 " + name + "年龄 " + age + "男孩? " + isboy);
29.
30. super.onCreate(savedInstanceState);
31. }
32.
33. }