Android 如何从BroadCastReceiver更新活动的UI
我正在学习Android 如何从BroadCastReceiver更新活动的UI,android,android-activity,broadcastreceiver,Android,Android Activity,Broadcastreceiver,我正在学习Android概念Activity和BroadCastReceiver。我想从BroadtCastReceiver更新Activity的内容,两者都在不同的java类中 有点像 MyActivity.java和MyBroadtCastReceiver.java 在安卓系统中可以做到这一点吗?是的,这是可能的。我就是这么做的。 i类从(BackgroundActivity.java)发送广播: 它将接收广播的类(SendCode.java): 我在onPause中注销了它 this.un
Android
概念Activity
和BroadCastReceiver
。我想从BroadtCastReceiver
更新Activity
的内容,两者都在不同的java类中
有点像
MyActivity.java
和MyBroadtCastReceiver.java
在安卓系统中可以做到这一点吗?是的,这是可能的。我就是这么做的。 i类从(BackgroundActivity.java)发送广播: 它将接收广播的类(SendCode.java): 我在onPause中注销了它
this.unregisterReceiver(broadcastBufferReceiver);
像这样试试,它可能会对你有帮助 在活动的oncreate方法中定义此方法,您要在其中更新ui
BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//your code to update ui
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("giveyourappname"));
try{
ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
Log.d("Activity", "Current Activity ::" + taskInfo.get(0).topActivity.getClassName());
Log.d("Package", "Package Name : "+ componentInfo.getPackageName());
if(componentInfo.getPackageName().equals("your application package name")){
Intent intent = new Intent("giveyourappname");
//add data you wnat to pass in intent
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}catch(Throwable e){
e.printStackTrace();
}
在要更新ui的位置定义此操作
BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//your code to update ui
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("giveyourappname"));
try{
ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
Log.d("Activity", "Current Activity ::" + taskInfo.get(0).topActivity.getClassName());
Log.d("Package", "Package Name : "+ componentInfo.getPackageName());
if(componentInfo.getPackageName().equals("your application package name")){
Intent intent = new Intent("giveyourappname");
//add data you wnat to pass in intent
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}catch(Throwable e){
e.printStackTrace();
}
试试看{
ActivityManager am=(ActivityManager)this.getSystemService(ACTIVITY_服务);
List taskInfo=am.getRunningTasks(1);
ComponentName componentInfo=taskInfo.get(0).topActivity;
Log.d(“活动”,“当前活动::”+taskInfo.get(0.topActivity.getClassName());
Log.d(“包”,“包名:”+componentInfo.getPackageName());
if(componentInfo.getPackageName().equals(“您的应用程序包名称”)){
意向意向=新意向(“giveyourappname”);
//添加您想要传递的数据
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}捕获(可丢弃的e){
e、 printStackTrace();
}
在活动中注册一个新的BroadcastReceiver对象,使用与MyBroadtCastReceiver相同的意向筛选器。由于BroadcastReceiver和MyBroadtCastReceiver具有相同的目的过滤器,因此将调用它们的onReceive()。您想在活动中执行的任何更新都可以在BroadcastReceive的onReceive中完成 ABroadcastReceiver
可以以多种方式使用,但是当涉及到更新活动的UI组件这样的特定内容时,在它自己的Java类文件中声明/定义BroadcastReceiver
几乎没有什么好处
推理-广播接收器
必须事先了解活动
以及更新UI所需的操作。实际上,BroadcastReceiver
与活动
本身绑定,将其声明/定义为内部类是有意义的
另一个重要方面是活动
需要处于“运行”(即可见)状态,以保证对UI组件的操作。在这种情况下,在onResume()
中注册接收器和在onPause()
中注销接收器将有助于防止出现问题
使用一个通用模板,我会做如下事情
class MyActivity extends Activity {
boolean mIsReceiverRegistered = false;
MyBroadcastReceiver mReceiver = null;
// onCreate(...) here
@Override
protected void onResume() {
// Other onResume() code here
if (!mIsReceiverRegistered) {
if (mReceiver == null)
mReceiver = new MyBroadcastReceiver();
registerReceiver(mReceiver, new IntentFilter("YourIntentAction"));
mIsReceiverRegistered = true;
}
}
@Override
protected void onPause() {
if (mIsReceiverRegistered) {
unregisterReceiver(mReceiver);
mReceiver = null;
mIsReceiverRegistered = false;
}
// Other onPause() code here
}
private void updateUI(Intent intent) {
// Do what you need to do
}
private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
}
}
编辑:一些额外的注释
BroadcastReceiver
的生命周期介于进入和离开onReceive(…)
之间。一旦从onReceive(…)
返回,实例将保持休眠状态,等待下一次广播
与第1点直接相关-a广播接收器
不是为“重型提升”而设计的。基本上,onReceive(…)
方法应该尽可能简单。它调用的任何方法都应该尽可能轻量级…进入,完成你的工作,离开,然后等待下一次广播。如果更新UI需要花费一些时间(例如,通过重新查询数据库以获取大量数据),请考虑异步调用的调用代码(例如<代码> AycCastase)。
您可以这样做:
公共类MyActivity扩展了活动{
//用于侦听任务完成后发送的意图
//成功处理
专用广播接收器mUpdateReceiver=新广播接收器(){
@凌驾
公共void onReceive(上下文、意图){
新建UpdateUiTask().execute();
}
};
@凌驾
在Resume()上公共无效{
registerReceiver(mUpdateReceiver,新意向过滤器(
你的意图(行动);
super.onResume();
}
@凌驾
public void onPause(){
未注册接收人(mUpdateReceiver);
super.onPause();
}
//用于更新用户界面
私有类UpdateUiTask扩展异步任务{
@凌驾
受保护的void onPreExecute(){
}
@凌驾
受保护的字符串背景(无效…无效){
Context=getApplicationContext();
字符串result=“test”;
//将获得的数据放在后台任务之后。
返回结果;
}
@凌驾
受保护的void onPostExecute(字符串结果){
//TODO:UI更新
}
}
}
-s答案仅在活动当前处于活动状态时有效。
如果您不想在其他活动中声明/定义您的BroadcastReceiver(BR),或者即使应用程序不是前台应用程序,您也希望进行一些更改,那么您的解决方案将如下所示
首先,声明BR,并保存或覆盖需要在AcitCity中显示的数据
public class MyBR extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// override the data. Eg: save to SharedPref
}
}
然后在活动中,显示数据
TextView tv = findViewById(R.id.tv);
tv.setText(/*get the data Eg: from SharedPref*/);
您还应使用计时器刷新电视:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView tv = findViewById(R.id.tv);
tv.setText(/*get the data Eg: from SharedPref*/);
}
});
}
}, REFRESH_RATE, REFRESH_RATE);
刷新率可能是1秒左右,但由您决定。将您的广播接收器
设置为活动的内部类
@Squonk不,我不想设置内部类。我有类似于MyActivity.java和MyBroadtCastReceiver.java的东西。有没有办法做到这一点?好的,一些要点/问题。。。1.你为什么不想要一个内部类呢?2.你打算怎样登记这个接受者?3.如果接收器未通过活动注册
如何知道活动
在接收广播时是否实际存在?4.一般来说,答案是-不,你不能在任何情况下这样做
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView tv = findViewById(R.id.tv);
tv.setText(/*get the data Eg: from SharedPref*/);
}
});
}
}, REFRESH_RATE, REFRESH_RATE);