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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM