Ga *_*chi 5 android android-service android-activity localbroadcastmanager
我想开发一个包含三个活动和两个服务的Android应用程序.
名为WebClientService的第一个Service 使用Handler每30秒调用一次REST API,并且必须通过结果通知活动的Activity.它还必须通知名为DatabaseService的第二个服务,以便更新本地数据库.
数据库服务将被称为只有一次的onCreate(在应用程序崩溃和重启的情况下)的,只是一次活动的onRestart(以这种方式,我们有数据显示的情况下,出现了连接问题).由于WebClientService每隔30秒通知"活动"活动,因此活动将自动更新.
问题是:
通知更新活动活动和后台DatabaseService的最佳方法是什么?我的想法是在WebClientService中使用sendBroadcast()并在每个活动和DatabaseService中使用BroadcastReceiver,这是正确的方法吗?
我应该使用相同的方法进行AllMeetingRoomActivity和DatabaseService之间的通信,还是应该使用绑定服务?
谢谢
更新:DatabaseService不再是后台服务,而只是WebClientService和活动之间的db层的共享实例.
现在的问题是:这是一个很好的方法,只需将我的30秒更新写入本地数据库,并允许活动每隔几秒钟更新一次,只需从本地数据库读取?这会对性能产生太大影响吗?
语境:
遵循我到目前为止所实现的,但使用SettableFutures,因此一旦我明确了如何使它们有效地进行通信,就需要使用服务和广播重新实现:
public class MainActivity extends AppCompatActivity {
private TextView meetingsTextView;
private EditText mEdit, editSubject;
private final ConnectorInitializer clientInitializer = new ConnectorInitializer();
private AppConnector genericClient; // can use OutlookClient or a test client to talk with a mock server
@Override
protected void onCreate(Bundle savedInstanceState) {
// initializes client based on the settings in "config.json"
genericClient = clientInitializer.create(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
meetingsTextView = (TextView) findViewById(R.id.NowMeeting);
mEdit = (EditText)findViewById(R.id.editText);
editSubject = (EditText)findViewById(R.id.editSubject);
Futures.addCallback(genericClient.logon(this, scopes), new FutureCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
Log.d("APP", "-- Logged in. --");
databaseConnector.synchronouslyGetBackupFromLocalDatabase() // FUTURE
// callback here
// onSuccess, onFailure
}
@Override
public void onFailure(@NonNull Throwable t) {
Log.e("\n ~~~~>> logon \n", t.getMessage());
meetingsTextView.setText(R.string.Login_Failed);
}
});
}
/** At the moment the UI is not updated automatically every 30 seconds
* but manually using a refresh button
*/
public void getBookings(@SuppressWarnings("UnusedParameters") View view){
Log.d("APP", "Retrieve button clicked: "+(DateTime.now())+". Calling async getCalendar.");
meetingsTextView.setText(R.string.retrieving_events);
try{
Futures.addCallback( genericClient.getCalendarEvents(), new FutureCallback<String>(){
@Override
public void onSuccess(final String resultCalendars) {
Log.d("APP", "Success. Result: "+resultCalendars);
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("APP", "Calendars SUCCESSFULLY retrieved.");
String meetingsRetrieved = getString(R.string.calendar)+resultCalendars;
meetingsTextView.setText(meetingsRetrieved);
Toast.makeText(getApplicationContext(), "Success!", Toast.LENGTH_LONG).show();
}
});
databaseConnector.asyncUpdateLocalDbWithResults(); // FUTURE
// callback here
// onSuccess, onFailure
}
@Override
public void onFailure(@NonNull Throwable t) {
Log.e( "APP", "Calendar error. Cause: "+t.getLocalizedMessage() );
String retrieveError = "Retrieve error. \n\n\n"+t.getLocalizedMessage();
meetingsTextView.setText(retrieveError);
Toast.makeText(getApplicationContext(), "Fail!", Toast.LENGTH_LONG).show();
}
});
}catch(Exception ex){
Log.e("APP","Something went wrong in your code. Cause:"+ex);
}
}
Run Code Online (Sandbox Code Playgroud)
Hir*_*tel 10
使用LocalBroadcastManager.更多参考这里.
MyService.java:
private LocalBroadcastManager localBroadcastManager;
private final String SERVICE_RESULT = "com.service.result";
private final String SERVICE_MESSAGE = "com.service.message";
@Override
public void onCreate() {
super.onCreate();
// Other stuff
localBroadcastManager = LocalBroadcastManager.getInstance(this);
}
Run Code Online (Sandbox Code Playgroud)
在服务中添加以下方法,只要您想将服务中的数据更新为Activity,通过传递调用方法Arguments.
private void sendResult(String message) {
Intent intent = new Intent(SERVICE_RESULT);
if(message != null)
intent.putExtra(SERVICE_MESSAGE, message);
localBroadcastManager.sendBroadcast(intent);
}
Run Code Online (Sandbox Code Playgroud)
HomeActivity.java:
private BroadcastReceiver broadcastReceiver;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_home);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String s = intent.getStringExtra(MyService.SERVICE_MESSAGE);
// do something here.
}
};
}
@Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver((broadcastReceiver),
new IntentFilter(MyService.SERVICE_RESULT));
}
@Override
protected void onStop() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
super.onStop();
}
Run Code Online (Sandbox Code Playgroud)
希望这会帮助你.
我认为你的方法还可以BroadCastReceiver.但是,BroadCastReceiver应该用于全局目的(如2个应用程序之间的通信).如果您打算BroadCastReceiver仅用于您的应用程序,我更喜欢使用LocalBroadcastManager.LocalBroadcastManager只有您的应用才能捕获它,使用速度更快,更安全.
你的activitys和你之间的另一种沟通方式service是使用EventBus.它比使用BroadCastReceiver(特别是在它们之间传递数据)要容易得多.
更新:关于您的更新问题:
LocalBroadcastmanager通知您的活动进行更新.ExecutorService为每个使用一个线程execute(插入,更新...).还需要考虑的另一件事是更新,经常会非常非常快地耗尽您的手机电池.