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