静态广播和动态广播的区别
在Android中广播有两种实现方式:
- static broadcast
- dynamic broadcast
两种广播有如下区别:
- 生存期,静态广播的生存期可以比动态广播的长很多,因为静态广播很多都是用来对系统时间进行监听,比如我们可以监听手机开机。而动态广播会随着context的终止而终止
- 优先级动态广播的优先级比静态广播高
- 动态广播无需在AndroidManifest.xml中声明即可直接使用,也即动态;而静态广播则需要,有时候还要在AndroidManifest.xml中加上一些权限的声明
通过一个简单的例子说明静态和动态的用法:
(这里用到了widget作为桌面响应的显示)
widget部分的代码:
widget_provider.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="80dp"
android:minWidth="200dp"
android:initialKeyguardLayout="@layout/widget_layout">
</appwidget-provider>
widget_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<TextView
android:id="@+id/widget_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:textColor="#000000"
/>
</LinearLayout>
widget事件处理类-MyWidgetProvider.java:
package com.nightonke.ex_05;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
remoteViews.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
}
当然不要忘记在AndroidManifest.xml中对widget进行声明。
<!--Widget-->
<receiver
android:name=".MyWidgetProvider"
android:label="@string/app_name">
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider"
>
</meta-data>
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
</receiver>
静态广播部分代码
首先,对于静态广播,我们需要在AndroidManifest.xml声明。
<!--Static broadcast-->
<receiver android:name=".MyStaticBroadcastReceiver"/>
然后实现静态广播的接收器,在其中对widget进行更新。
public class MyStaticBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
remoteViews.setTextViewText(R.id.widget_text, intent.getStringExtra("MESSAGE"));
AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(
context.getApplicationContext(), MyWidgetProvider.class), remoteViews);
}
}
静态广播的发送也很简单:
sendStaticBroadcastButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MyStaticBroadcastReceiver.class);
intent.putExtra("MESSAGE", editText.getText().toString());
sendBroadcast(intent);
}
});
可以看到,静态广播不需要在代码中注册。
动态广播代码
首先不需要在AndroidManifest.xml声明。
同样的,我们需要一个接收器,在里面对widget进行更新。
public class MyDynamicBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
remoteViews.setTextViewText(R.id.widget_text, intent.getStringExtra("MESSAGE"));
AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(
context.getApplicationContext(), MyWidgetProvider.class), remoteViews);
}
}
最后,动态广播的发送,需要注册才会被接收器接收到。
myDynamicBroadcastReceiver = new MyDynamicBroadcastReceiver();
sendDynamicBroadcastButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// send a dynamic broadcast
// it can be received when registered
Intent intent = new Intent("android.appwidget.action.APPWIDGET_UPDATE");
intent.putExtra("MESSAGE", editText.getText().toString());
sendBroadcast(intent);
}
});
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
IntentFilter dynamic_filter = new IntentFilter();
dynamic_filter.addAction("android.appwidget.action.APPWIDGET_UPDATE");
if (registered) {
unregisterReceiver(myDynamicBroadcastReceiver);
registerButton.setText("Register");
} else {
registerReceiver(myDynamicBroadcastReceiver, dynamic_filter);
registerButton.setText("Unregister");
}
registered = !registered;
}
});
结果:
对于静态广播,直接点击即可发送:
发送后:对于动态广播,必须先注册了才会被接收到:
发送后:
注意上面的左图点击SEND DYNAMIC BROADCAST按钮是没有用的,一定要点了REGISTER按钮桌面的widget才会呈右图样子。