zoukankan      html  css  js  c++  java
  • Android 广播 Broadcast学习

     

    Android Broadcast 广播

    进程内本地广播

      如果你是在你的应用之内使用广播,即不需要跨进程,考虑使用LocalBroadcastManager ,这样更有效率(因为不需要跨进程通信),并且你不用考虑一些其他应用可以发送或接收你的广播相关的安全问题。

      下面介绍更一般的方法。

    广播的两种注册方法

      广播有静态和动态两种注册方法:

      静态注册:在AndroidManifest.xml中加上<receiver> 标签。

      动态注册:通过 Context.registerReceiver()方法进行注册。比如在onResume中注册,在onPause中注销。

      附上例子(例子中的布局、MyReceiver类,常量类都是相同的,在前面列出):

      布局文件都一样:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".DemoBroadcastActivity" >
    
        <TextView
            android:id="@+id/helloText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />
    
        <Button
            android:id="@+id/sendBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/helloText"
            android:text="@string/send" />
    
    </RelativeLayout>

      自己写的Receiver类:

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.widget.Toast;
    
    public class MyReceiver extends BroadcastReceiver
    {
    
        
        public MyReceiver()
        {
            super();
            Log.d(AppConstants.LOG_TAG, "Receiver constructor");
        }
    
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Log.d(AppConstants.LOG_TAG, "onReceive");
            String message = intent.getStringExtra(AppConstants.MSG_KEY);
            Log.i(AppConstants.LOG_TAG, message);
            Toast.makeText(context, "Received! msg: " + message, Toast.LENGTH_SHORT).show();
        }
        
        
    
    }

      应用常量:

    public class AppConstants
    {
        public static final String LOG_TAG = "Broadcast";
        public static final String MSG_KEY = "msg";
        
        public static final String BROADCAST_ACTION ="com.example.demobroadcast.BroadcastAction";
    
    }

      下面就是不同的部分了!

      静态注册的实例代码:

      静态注册是在manifest文件中进行:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.demobroadcast"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        <uses-permission android:name="android.permission.SEND_SMS" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.demobroadcast.DemoBroadcastActivity"
                android:label="@string/app_name" >
                <intent-filter android:priority="1000">
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <receiver
                android:name="com.example.demobroadcast.MyReceiver">
                <intent-filter  >
                    <action android:name="com.example.demobroadcast.BroadcastAction" />
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>

      所以Java代码:

    package com.example.demobroadcast;
    
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.app.Activity;
    import android.content.Intent;
    
    public class DemoBroadcastActivity extends Activity
    {
        private Button sendBtn = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_demo_broadcast);
    
            sendBtn = (Button) findViewById(R.id.sendBtn);
    
            sendBtn.setOnClickListener(new OnClickListener()
            {
    
                @Override
                public void onClick(View v)
                {
                    Intent intent = new Intent();
                    intent.setAction(AppConstants.BROADCAST_ACTION);
                    intent.putExtra("msg", "圣骑士wind");
                    sendBroadcast(intent);
    
                }
            });
        }
    
    }

      动态注册的实例代码:

      动态注册是在Java代码中进行:

    package com.example.demobroadcast2;
    
    import com.example.demobroadcast.R;
    
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.app.Activity;
    import android.content.Intent;
    import android.content.IntentFilter;
    
    public class DemoBroadcastActivity extends Activity
    {
        private Button sendBtn = null;
        
        private MyReceiver mReceiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_demo_broadcast);
    
            sendBtn = (Button) findViewById(R.id.sendBtn);
    
            sendBtn.setOnClickListener(new OnClickListener()
            {
    
                @Override
                public void onClick(View v)
                {
                    Intent intent = new Intent();
                    intent.setAction(AppConstants.BROADCAST_ACTION);
                    intent.putExtra("msg", "圣骑士wind");
                    sendBroadcast(intent);
    
                }
            });
        }
        
        @Override
        protected void onResume()
        {
            super.onResume();
            
            mReceiver = new MyReceiver();
            IntentFilter intentFilter= new IntentFilter(AppConstants.BROADCAST_ACTION);
            registerReceiver(mReceiver, intentFilter);
        }
        
        @Override
        protected void onPause()
        {
            super.onPause();
            
            unregisterReceiver(mReceiver);
        }
        
        @Override
        protected void onDestroy()
        {
            super.onDestroy();
        }
    
    }

      所以Manifest文件中不需要添加标签,正常就行。

    两种广播

      Normal broadcasts

      通过 Context.sendBroadcast发送,完全是异步的(asynchronous)。所有的接收器以不确定的顺序运行,通常是同时。

      这样更有效率,但是也意味着接收器不能传递结果,也不能退出广播。

      Ordered broadcasts

      通过 Context.sendOrderedBroadcast发送。一次只向一个接收器发送。

      由于每个接收器按顺序执行,它可以向下一个接收器传递结果,也可以退出广播不再传递给其他接收器。

      接收器运行的顺序可以通过 android:priority 属性来控制,相同优先级的接收器将会以随机的顺序运行。

    接收器的生命周期

      一个BroadcastReceiver的对象只在 onReceive(Context, Intent)被调用的期间有效,一旦从这个方法返回,系统就认为这个对象结束了,不再活跃。

      这对你在onReceive中能做什么有很大的影响:不能做任何需要的操作(anything that requires asynchronous operation is not available)。

      因为你需要从方法返回去进行你的异步操作,而返回时BroadcastReceiver的对象已经不再活跃了,系统可以(在异步操作完成前)任意杀死它的进程。

      特别地,不可以在BroadcastReceiver中显示对话框或者绑定一个service,前者应该用 NotificationManager,后者应该用Context.startService()

     

    参考资料

      官方文档BroadcastReceiver:

      http://developer.android.com/reference/android/content/BroadcastReceiver.html

      LocalBroadcastManager:

      http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html 

      Training: Manipulating Broadcast Receivers On Demand

      http://developer.android.com/training/monitoring-device-state/manifest-receivers.html

      receiver标签

      http://developer.android.com/guide/topics/manifest/receiver-element.html

  • 相关阅读:
    类的加载过程
    ASCII码表
    uboot main_loop函数分析
    串行CPU设计
    __attribute__ ((section(".text")))的测试
    NandFlash
    测试gcc的优化选项
    如何编写一个简单的makefile
    UBOOT的多支持性与可裁剪性
    函数指针的使用
  • 原文地址:https://www.cnblogs.com/mengdd/p/3135431.html
Copyright © 2011-2022 走看看