我正在学习与 Android
相关的概念,包括Activity
和BroadCastReceiver
。我想要在两个不同的Java类中,从BroadtCastReceiver
更新Activity
的内容。
大致就是这样:
MyActivity.java
和 MyBroadtCastReceiver.java
在Android中能实现这个功能吗?
我正在学习与 Android
相关的概念,包括Activity
和BroadCastReceiver
。我想要在两个不同的Java类中,从BroadtCastReceiver
更新Activity
的内容。
大致就是这样:
MyActivity.java
和 MyBroadtCastReceiver.java
在Android中能实现这个功能吗?
BroadcastReceiver
可以用于许多方面,但是当涉及到更新Activity
的UI组件这样的特定情况时,在其自己的Java类文件中声明/定义BroadcastReceiver
没有太大的优势。
原因在于,BroadcastReceiver
必须具有先前对Activity
的某些"了解",以及更新UI所需的操作。 实际上,BroadcastReceiver
与Activity
本身相结合,将其声明/定义为内部类是有意义的。
另一个重要方面是,Activity
需要处于"运行"(即可见)状态,以保证操作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(...)
返回,实例将保持不活动状态等待下一个广播。BroadcastReceiver
并不适用于“重活”。基本上,onReceive(...)
方法应该尽可能简单。任何它调用的方法也应尽可能轻量级...开始执行你的内容,然后就退出,等待下一个广播。如果更新UI需要一些时间(例如通过重新查询大量数据的数据库来更新ListView
),请考虑调用执行异步操作的代码(例如AsyncTask
)LocalBroadCastManager
来完成相同的任务吗? - N SharmaBroadcastReceiver
启动长时间运行的后台线程。请参见此处下方的Effects process state:https://developer.android.com/guide/components/broadcasts.html - Rany Albeg Wein是的,这是可能的。这就是我的做法。 我从哪个类发送广播(BackgroundActivity.java):
public static final String BROADCAST_BUFFER_SEND_CODE = "com.example.SEND_CODE";
onCreate(){
bufferIntentSendCode = new Intent(BROADCAST_BUFFER_SEND_CODE);
}
private void sendBufferingBroadcastSendCode() {
bufferIntentSendCode.putExtra("buffering", "1");
sendBroadcast(bufferIntentSendCode);
}
onResume(){
registerReceiver(broadcastBufferReceiver, new IntentFilter(BackgroundActivity.BROADCAST_BUFFER_SEND_CODE));
}
// set up broadcast receiver
private BroadcastReceiver broadcastBufferReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent bufferIntent) {
SendCode.this.LoadMessages(alarmNumber);
}
};
我在onPause中取消注册它。
this.unregisterReceiver(broadcastBufferReceiver);
Squonk的答案只在Activity当前处于活动状态时有效。 如果您不想在其他Activity中声明/定义BroadcastReceiver(BR),或者如果您想进行一些更改,即使应用程序不在前台,那么您的解决方案将类似于以下内容。
首先,您声明BR并保存或覆盖在Acitvity中显示所需的数据。
public class MyBR extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// override the data. Eg: save to SharedPref
}
}
然后在Activity中展示数据
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);
REFRESH_RATE 可以设定为 1 秒,但由您决定。
You can do like this:
public class MyActivity extends Activity{
// used to listen for intents which are sent after a task was
// successfully processed
private BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
new UpdateUiTask().execute();
}
};
@Override
public void onResume() {
registerReceiver(mUpdateReceiver, new IntentFilter(
YOUR_INTENT_ACTION));
super.onResume();
}
@Override
public void onPause() {
unregisterReceiver(mUpdateReceiver);
super.onPause();
}
// used to update the UI
private class UpdateUiTask extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... voids) {
Context context = getApplicationContext();
String result = "test";
// Put the data obtained after background task.
return result;
}
@Override
protected void onPostExecute(String result) {
// TODO: UI update
}
}
}
你可以试试这样做,可能会有帮助。
在你想要更新UI的Activity的onCreate方法中定义这个方法:
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"));
在你想要更新UI的地方定义这个操作。
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();
}
getRunningTasks()
的文档中得知:注意:此方法仅用于调试和展示任务管理用户界面。这不应该用于应用程序核心逻辑,例如根据此处找到的信息决定不同行为。此类用法不受支持,并且将来可能会出现问题。例如,如果多个应用程序可以同时运行,则基于此处数据含义的控制流假设将是不正确的。 - LordRaydenMKActivity
的onResume()
和onPause()
方法中注册接收器。这样,当接收器的onReceive(...)
方法被调用时,您可以保证您的Activity
处于“运行”状态。为一个需要更新特定UI元素的BroadcastReceiver
创建一个单独的Java类并没有任何优势。 - Squonk