ZNDS智能电视网 推荐当贝市场

TV应用下载 / 资源分享区

软件下载 | 游戏 | 讨论 | 电视计算器

综合交流 / 评测 / 活动区

交流区 | 测硬件 | 网站活动 | Z币中心

新手入门 / 进阶 / 社区互助

新手 | 你问我答 | 免费刷机救砖 | ROM固件

查看: 8628|回复: 0
上一主题 下一主题
[教程]

Android软件开发之应用程序之间的通信介绍(十八)

[复制链接]
跳转到指定楼层
楼主
发表于 2013-8-28 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Android软件开发之应用程序之间的通信介绍   
     
   
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{   
       
        /**更新时间**/   
        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通知栏。   
   
   
   
屏幕上方为弹出的Notifation通知栏   
   
     
   
将Notifation通知栏拉下后会出现相应的信息   
     
  1. 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. 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.                 <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. 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.         <receiver android:name=".MyBootReceiver" >   
           <intent-filter>   
              <action android:name="android.intent.action.BOOT_COMPLETED" />   
          </intent-filter>   
        </receiver>
复制代码
注意加入权限   
  1.         <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
复制代码
在BroadcastRecevier中接收开机广播  然后打开service 就可以实现开机启动service。   
  1. 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 。   
     
       读下面这段代码 大家会发现intent与bandle 传递数值的方式基本一样为什么还要分成两个呢? 确实他们两个传递的数值的方式非常类似, 他们两个的区别就是Intent属于把零散的数据传递过去 而bundle则是把零散的数据先放入bundle 然后在传递过去。我举一个例子 比如我们现在有3个activity  A.B.C  须要把A的数据穿给B然后在穿给C ,如果使用intent一个一个传递 须要在A类中一个一个传递给B 然后B类中获取到所有数值  然后在一个一个传递给C  这样很麻烦 但是 如果是bundle的话 B类中直接将bundler传递给C 不用一个一个获得具体的值  然后在C类中直接取得解析数值。   
   
传递   
  1.         /**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. 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);   
        }   
       
    }
复制代码
最后还是那句老话如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习   
第九讲 应用程序之间的通信介绍.rar(306.01 KB, 下载次数: 427)[/I]2011-9-3 00:24 上传点击文件名   下载积分: 下载豆 -2

上一篇:对通讯录的各项操作,完整版,经过测试,方便后来者
下一篇:Android腾讯微博客户端开发四:微博发送篇(QQ表情,@搜索)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|新帖|标签|软件|Sitemap|ZNDS智能电视网 ( 苏ICP备2023012627号 )

网络信息服务信用承诺书 | 增值电信业务经营许可证:苏B2-20221768 丨 苏公网安备 32011402011373号

GMT+8, 2024-5-7 19:55 , Processed in 0.065707 second(s), 13 queries , Redis On.

Powered by Discuz!

监督举报:report#znds.com (请将#替换为@)

© 2007-2024 ZNDS.Com

快速回复 返回顶部 返回列表