android中的通信机制总结

 

第一种:使用handler来进行通信
   handler 大家可以把它想象成主线程(UI线程)的一个子线程,它可以给主线程(UI线程)发送数据从而更新主线程(UI线程)的UI与逻辑,handler 是一个子线程所以它的耗时操作不会阻塞主线程,大家都知道在Android的开发中如果代码中某个地方阻塞主线程超过5秒的话系统会提示ANR (系统提示强制关闭)所以在耗时操作上我们可以考虑开启一个子线程避免ANR。  handler会向主线程发送消息 会以队列的形式排列着配合等待主线程更新UI 逻辑 等等。

  1. public class HandlerActivity extends Activity implements Runnable{
  2. /**更新时间**/
  3. public final static int UPDATE_TIME =0;
  4. /**更新时间成功**/
  5. public final static int UPDATE_COMPLETED =1;
  6. /**记录显示时间 超过10秒结束线程**/
  7. private int mShowNumber = 0;
  8. /**开始计时按钮**/
  9. private Button mButton = null;
  10. /**计时显示内容**/
  11. private TextView mTextView = null;
  12. /**线程**/
  13. private Thread mThread = null;
  14. /**线程关闭的标志**/
  15. private boolean mRunning = false;
  16. Handler handler = new Handler() {
  17. @Override
  18. public void handleMessage(Message msg) {
  19. Bundle bundle= msg.getData();
  20. //通过key的名称拿到它的值
  21. String  number = bundle.getString("number");
  22. //msg.what为handler接收到的消息编号
  23. switch(msg.what) {
  24. case UPDATE_TIME:
  25. mTextView.setText("正在更新时间" + number);
  26. break;
  27. case UPDATE_COMPLETED:
  28. mTextView.setText("更新完毕");
  29. break;
  30. }
  31. super.handleMessage(msg);
  32. }
  33. };
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. setContentView(R.layout.handler);
  37. /**拿到button 与  TextView 对象**/
  38. mButton = (Button)findViewById(R.id.button0);
  39. mTextView = (TextView)findViewById(R.id.textView0);
  40. mThread = new Thread(this);
  41. mButton.setOnClickListener(new OnClickListener() {
  42. @Override
  43. public void onClick(View arg0) {
  44. /**点击按钮后开始线程开始计时**/
  45. mRunning = true;
  46. mThread.start();
  47. }
  48. });
  49. mTextView.setText("点击按钮开始更新时间");
  50. super.onCreate(savedInstanceState);
  51. }
  52. public void ShowDialog(String string) {
  53. AlertDialog.Builder builder = new AlertDialog.Builder(
  54. HandlerActivity.this);
  55. builder.setIcon(R.drawable.icon);
  56. builder.setTitle(string);
  57. builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  58. public void onClick(DialogInterface dialog, int whichButton) {
  59. finish();
  60. }
  61. });
  62. builder.show();
  63. }
  64. @Override
  65. public void run() {
  66. while (mRunning) {
  67. try {
  68. mShowNumber++;
  69. /** 把须要的数据放入bandle中 **/
  70. Bundle bandle = new Bundle();
  71. bandle.putString("number", String.valueOf(mShowNumber));
  72. /** 设置这条信息的编号为更新时间 **/
  73. /** 将bandle写入message中 **/
  74. /** 最后将这个message发送出去 **/
  75. /** mShowNumber小于10更新时间 否则更新完毕 **/
  76. Message msg = new Message();
  77. if(mShowNumber <=10) {
  78. msg.what = UPDATE_TIME;
  79. }else {
  80. mRunning = false;
  81. msg.what = UPDATE_COMPLETED;
  82. }
  83. msg.setData(bandle);
  84. handler.sendMessage(msg);
  85. Thread.sleep(1000);
  86. } catch (InterruptedException e) {
  87. e.printStackTrace();
  88. }
  89. }
  90. }
  91. }

2.Notifation通知栏信息
       Notifation通知栏会在屏幕上方向用户提示信息 但是不会打断用户正在阅读的内容,除非用户手动将 Notifation通知栏拉下。 Notifation的好处就是在于不会影响用户的操作,比如用户正在阅读非常重要的信息这时候帮他直接打开一个activity会非常不合适 因为直接影响到了他当时的操作行为 所以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. // 得到通知消息的管理器对象,负责管理 Notification 的发送与清除消息等
  8. mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
  9. // 创建Notification对象 参数分别代表 通知栏 中显示的图标 显示的标题 显示的时间
  10. notification = new Notification(R.drawable.jay,
  11. "Android专业开发群", System.currentTimeMillis());
  12. // 设置在通知栏中点击后Notification自动消失
  13. notification.flags = Notification.FLAG_AUTO_CANCEL;
  14. //设置点击后转跳的新activity
  15. Intent intent = new Intent(this, MyShowActivity.class);
  16. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
  17. //通过bundle可以带一些数据过去 这里将字符串传递了过去
  18. Bundle bundle = new Bundle();
  19. bundle.putString("name", "从Notification转跳过来的");
  20. intent.putExtras(bundle);
  21. //设置通知栏中显示的内容
  22. PendingIntent contentIntent = PendingIntent.getActivity(this,
  23. R.string.app_name, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  24. notification.setLatestEventInfo(this, "Android专业开发群",
  25. "QQ群号 164257885", contentIntent);
  26. Button button0 = (Button)findViewById(R.id.button0);
  27. button0.setOnClickListener(new OnClickListener() {
  28. @Override
  29. public void onClick(View arg0) {
  30. //打开这个Notification通知
  31. mManager.notify(0, notification);
  32. }
  33. });
  34. Button button1 = (Button)findViewById(R.id.button1);
  35. button1.setOnClickListener(new OnClickListener() {
  36. @Override
  37. public void onClick(View arg0) {
  38. //关闭这个Notification通知
  39. mManager.cancelAll();
  40. }
  41. });
  42. super.onCreate(savedInstanceState);
  43. }
  44. }

3.广播的发送与接收

Android开发中如果须要对两个完全没关系的程序之间进行通信 就可以使用发送广播与接收广播的机制来实现 ,例如程序A发送了一个广播 程序B接受到 做一些事情 这样就达到了相互的通讯。

  1. public class BroadcastActivity extends Activity {
  2. Button mButton0 = null;
  3. Button mButton1 = null;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. setContentView(R.layout.broadcast);
  7. mButton0 = (Button)findViewById(R.id.button0);
  8. mButton0.setOnClickListener(new OnClickListener() {
  9. @Override
  10. public void onClick(View arg0) {
  11. Intent intent = new Intent(MyService.SEND_OK_MESSAGE);
  12. intent.putExtra("name", "您发送了OK这条广播哦");
  13. sendBroadcast(intent);
  14. }
  15. });
  16. mButton1 = (Button)findViewById(R.id.button1);
  17. mButton1.setOnClickListener(new OnClickListener() {
  18. @Override
  19. public void onClick(View arg0) {
  20. Intent intent = new Intent(MyService.SEND_CANCLE_MESSAGE);
  21. intent.putExtra("name", "您发送了Cancle这条广播哦");
  22. sendBroadcast(intent);
  23. }
  24. });
  25. //启动Service
  26. Intent i = new Intent(this, MyService.class);
  27. startService(i);
  28. super.onCreate(savedInstanceState);
  29. }
  30. }
  1. 接收广播的话 我们开启一个service 在service中通过BroadcastReceiver 来接收广播 前提是须要接收的广播须要在onStart()中注册一下 在AndroidManifest.xml中可以过滤只接收须要接收的广播、
  2. view plain
  3. <service android:name=".MyService">
  4. <intent-filter>
  5. <action android:name="cn.m15.xys.MyService"></action>
  6. </intent-filter>
  7. <intent-filter>
  8. <action android:name="send.ok.message" />
  9. <action android:name="send.cancle.message" />
  10. </intent-filter>
  11. </service>
  12. 在onStart()中注册了程序中所需要的两个广播
  13. view plain
  14. public class MyService extends Service {
  15. public final static String SEND_OK_MESSAGE = "send.ok.message";
  16. public final static String SEND_CANCLE_MESSAGE = "send.cancle.message";
  17. private BroadcastReceiver myBroadCast = new BroadcastReceiver() {
  18. @Override
  19. public void onReceive(Context context, Intent intent) {
  20. String action = intent.getAction();
  21. if (action.equals(SEND_OK_MESSAGE)) {
  22. Toast.makeText(context, "接收到了一条广播为" + SEND_OK_MESSAGE, Toast.LENGTH_LONG).show();
  23. }else if(action.equals(SEND_CANCLE_MESSAGE)) {
  24. Toast.makeText(context, "接收到了一条广播为" + SEND_CANCLE_MESSAGE, Toast.LENGTH_LONG).show();
  25. }
  26. }
  27. };
  28. @Override
  29. public void onCreate() {
  30. super.onCreate();
  31. }
  32. @Override
  33. public void onStart(Intent intent, int startId) {
  34. //注册这两个广播
  35. IntentFilter myFilter = new IntentFilter();
  36. myFilter.addAction(SEND_OK_MESSAGE);
  37. myFilter.addAction(SEND_CANCLE_MESSAGE);
  38. this.registerReceiver(myBroadCast, myFilter);
  39. super.onStart(intent, startId);
  40. }
  41. @Override
  42. public IBinder onBind(Intent arg0) {
  43. return null;
  44. }
  45. }
  46. 这里注意一下 service如果没有起来 我们是接收不到广播的 所以一定要保证接收的时候service是开启的,上例中的service是在打开activity时开启的 但是如果用户把手机关掉然后在开机 , 这样的话service就不是打开状态 这样就非常危险了因为这时scrvice就接收不到任何消息了除非用户再次进activity 才会帮他打开scrvice 所以我们可以在用户开机后就直接将scrvice打开,具体的实现方式如下
  47. 在AndroidManifest.xml中注册一个开机广播  这个广播系统只会在开机发出而且只会发出一次 所以我们接收这个广播就可以知道手机是否为开机状态
  48. view plain
  49. <receiver android:name=".MyBootReceiver" >
  50. <intent-filter>
  51. <action android:name="android.intent.action.BOOT_COMPLETED" />
  52. </intent-filter>
  53. </receiver>
  54. 注意加入权限
  55. view plain
  56. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  57. 在BroadcastRecevier中接收开机广播  然后打开service 就可以实现开机启动service。
  58. view plain
  59. public class MyBootReceiver extends BroadcastReceiver {
  60. /**开机广播**/
  61. static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
  62. @Override
  63. public void onReceive(Context context, Intent intent) {
  64. /**如果为开机广播则开启service**/
  65. if (intent.getAction().equals(BOOT_COMPLETED)) {
  66. Intent i = new Intent(context, MyService.class);
  67. context.startService(i);
  68. }
  69. }
  70. }

4.Activity与Activity之间的转跳

在软件应用的开发中肯定会有多个Activity     这样它们之间就会存在相互转跳的关系      转跳的实现方式还是使用Intent  然后startActivity  ,当然转跳的话是可以带数据过去的。比如从A跳到B 可以把A中的一些数据通过Intent传递给B 。

  1. 读下面这段代码 大家会发现intent与bandle 传递数值的方式基本一样为什么还要分成两个呢? 确实他们两个传递的数值的方式非常类似, 他们两个的区别就是Intent属于把零散的数据传递过去 而bundle则是把零散的数据先放入bundle 然后在传递过去。我举一个例子 比如我们现在有3个activity  A.B.C  须要把A的数据穿给B然后在穿给C ,如果使用intent一个一个传递 须要在A类中一个一个传递给B 然后B类中获取到所有数值  然后在一个一个传递给C  这样很麻烦 但是 如果是bundle的话 B类中直接将bundler传递给C 不用一个一个获得具体的值  然后在C类中直接取得解析数值。
  2. 传递
  3. view plain
  4. /**Activity之间传递值**/
  5. Button botton3 = (Button)findViewById(R.id.button3);
  6. botton3.setOnClickListener(new OnClickListener() {
  7. @Override
  8. public void onClick(View arg0) {
  9. Intent intent = new Intent(mContext,ShowActivity.class);
  10. //使用intent.putExtra()直接传递
  11. intent.putExtra("name", "雨松MOMO");
  12. intent.putExtra("age", 25);
  13. intent.putExtra("boy", true);
  14. //把数值放进bundle 然后在把整个bundle通过intent.putExtra()传递
  15. Bundle bundle = new Bundle();
  16. bundle.putString("b_name", "小可爱");
  17. bundle.putInt("b_age", 23);
  18. bundle.putBoolean("b_boy", false);
  19. //在这里把整个bundle 放进intent中
  20. intent.putExtras(bundle);
  21. //开启一个新的 activity 将intent传递过去
  22. startActivity(intent);
  23. }
  24. });
  25. 接收
  26. view plain
  27. public class ShowActivity extends Activity {
  28. @Override
  29. protected void onCreate(Bundle savedInstanceState) {
  30. setContentView(R.layout.my);
  31. Intent intent = getIntent();
  32. String name = intent.getStringExtra("name");
  33. //第二个参数为默认值 意思就是如果在intent中拿不到的话
  34. //就用默认值
  35. int age  = intent.getIntExtra("age", 0);
  36. boolean isboy = intent.getBooleanExtra("boy", false);
  37. TextView textView0 = (TextView)findViewById(R.id.text0);
  38. textView0.setText("姓名  " + name + "年龄 " + age + "男孩?  " + isboy);
  39. Bundle bundle = intent.getExtras();
  40. name = bundle.getString("b_name");
  41. //第二个参数为默认值 意思就是如果在bundle中拿不到的话
  42. //就用默认值
  43. age = bundle.getInt("b_age",0);
  44. isboy = bundle.getBoolean("b_boy", false);
  45. TextView textView1 = (TextView)findViewById(R.id.text1);
  46. textView1.setText("姓名  " + name + "年龄 " + age + "男孩?  " + isboy);
  47. super.onCreate(savedInstanceState);
  48. }
  49. }
上一篇:Directive间的通信


下一篇:底部导航栏-----FragmentTabHost