今天学习了下android的BroadcastReceiver的两种实现方式(1.配置文件注册和后台程序注册方式)。
学习的目标:会用两种方式实现广播接收器,发送广播,两者区别及android里面一个让我很郁闷的情况,哪个线程创建的UI组件只能由哪个线程来操作。
下面是代码
/**
* 入口
*/
public class MainActivity extends Activity {
//这里的activity_main.xml就不贴出来了,就是一堆button
Button sendButtonId;
Button sendButton2Id;
Button registerReciver;
Button deleteReciver;
TextView textView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendButtonId = (Button) findViewById(R.id.sendButtonId);
registerReciver = (Button) findViewById(R.id.registerReciver);
deleteReciver = (Button) findViewById(R.id.deleteReciver);
sendButton2Id = (Button) findViewById(R.id.sendButton2Id);
sendButtonId.setOnClickListener(licen);
sendButton2Id.setOnClickListener(licen);
registerReciver.setOnClickListener(licen);
deleteReciver.setOnClickListener(licen);
textView = (TextView)findViewById(R.id.textViewId);
}
OnClickListener licen = new OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sendButtonId:
sendReciver();
break;
case R.id.sendButton2Id:
sendReciver2();
break;
case R.id.registerReciver:
registerReciver();
break;
case R.id.deleteReciver:
deleteReciver();
break;
}}};
/**
* 发送自定义广播android.test.reciver
*/
private void sendReciver() {
Intent i = new Intent("android.test.reciver");
sendBroadcast(i);
}
/**
* 发送自定义广播android.test.reciver2.register
*/
private void sendReciver2() {
Intent i = new Intent("android.test.reciver2.register");
sendBroadcast(i);
}
/**
* 注册广播接收器,这种程序注册方式会随着应用的关闭而关闭
*/
BroadCaseRecTest dateReceiver ;
private void registerReciver() {
dateReceiver = new BroadCaseRecTest();
IntentFilter filter = new IntentFilter();
filter.addAction("android.test.reciver2.register");
MainActivity.this.registerReceiver(dateReceiver, filter);
}
/**
* 销毁广播接收器
*/
private void deleteReciver() {
MainActivity.this.unregisterReceiver(dateReceiver);
/*Thread1Test thread1 = new Thread1Test(this);
Thread thread = new Thread(thread1);
thread.start();这里开启线程去更新textView,但实际是会报错的*/
}
//更新textView方法
public void setTextsd(String hello) {
textView.setText(hello);
}
}
在AndroidManifest.xml里配置第一种方式
android:name="com.br.broadcastreceiver.DefineBroadcastReceiver">
第一个接收器
/**
* 接收器的实现有两种方法
* (1)在AndroidManifest.xml文件里注册,这种方法在应用程序关闭后接收器依然在运行
* (2)通过程序代码register方法创建接收器,这种方式的接收器随着程序的关闭而关闭
* 这里定义的是为第一种情况服务的广播接收器类
* 功能:将广播内容放入Notification里
* 点击Notification内容后Notification消失
* 跳转到一个NotificationActivity
*/
public class DefineBroadcastReceiver extends BroadcastReceiver {
@SuppressWarnings("deprecation")
@Override
public void onReceive(Context context, Intent arg1) {
// TODO Auto-generated method stub
PendingIntent pending = PendingIntent.getActivity(context, 0, new Intent(
context, NotificationActivity.class), 0);
Notification noticed = new Notification();
noticed.icon = R.drawable.u68_normal;
noticed.tickerText = "状态栏通知";
noticed.defaults = Notification.DEFAULT_SOUND;
noticed.setLatestEventInfo(context, "这是一个状态栏通知", "查看",pending);
NotificationManager noticedManager = (NotificationManager)
context.getSystemService(context.NOTIFICATION_SERVICE);
noticed.flags|=Notification.FLAG_AUTO_CANCEL;
noticedManager.notify(1, noticed);
}
}
第二个接收器
/**
* 自定义一个广播接收器接收register类型的广播
* 并将广播内容放入Notification里
* 点击Notification内容后Notification消失
* 跳转到一个NotificationActivity
*/
public class BroadCaseRecTest extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PendingIntent pending = PendingIntent.getActivity(context, 0, new Intent(
context, NotificationActivity.class), 0);
Notification noticed = new Notification();
noticed.icon = R.drawable.u68_normal;
noticed.tickerText = "状态栏通知";
noticed.defaults = Notification.DEFAULT_SOUND;
noticed.setLatestEventInfo(context, "我是一个后台注册的reciver", "查看",pending);
NotificationManager noticedManager = (NotificationManager)
context.getSystemService(context.NOTIFICATION_SERVICE);
noticed.flags|=Notification.FLAG_AUTO_CANCEL;
noticedManager.notify(1, noticed);
}
}
一个线程类
/**
*这里是想在这个现场里更新TextView,但结果是不可行的。
*因为android规定所有UI组件必须只能由创建这个组件的线程操作。
*/
public class Thread1Test implements Runnable {
MainActivity activity;
public Thread1Test(MainActivity activity) {
this.activity = activity;
}
@Override
public void run() {
int a=0;
while(true) {
if(a<20) {
/**
* 这里会报错,是因为android规定所有UI组件必须只能由创建这个组件的线程操作。
* 所以这里会报错(因为他是在另外一个线程里去操作了)虽然这个activity是创建TextView的对象,但并不是创建它的线程
* 如果非要在另一个线程里改变组件就需要用到SurfaceView 这里不做介绍了
*/
activity.setTextsd(a+"");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
} else {
break;
}}}}