【发布时间】:2016-04-10 03:42:47
【问题描述】:
我想开发一个包含三个活动和两个服务的 Android 应用程序。
第一个名为 WebClientService 的服务使用 Handler 每 30 秒调用一次 REST API,并且必须将结果通知活动的 Activity。 它还必须通知名为 DatabaseService 的第二个服务,以便更新本地数据库。
数据库服务将仅在活动的一次onCreate 调用(以防应用崩溃和重启)并且仅在onRestart 调用一次(这样我们就有了数据以防万一出现连接问题)。借助每 30 秒通知“活动”活动的 WebClientService,活动将保持自身更新。
问题是:
通知活动活动和后台 DatabaseService 更新的最佳方式是什么? 我的想法是在 WebClientService 中使用 sendBroadcast() 并在每个活动和 DatabaseService 中使用 BroadcastReceiver,这是正确的方法吗?
我应该使用相同的方法在 AllMeetingRoomActivity 和 DatabaseService 之间进行通信还是应该使用Bound Service?
谢谢
更新: 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);
}
}
【问题讨论】:
-
你能用一些伪代码解释一下吗?
-
我很困惑,因为我不知道你真正想做什么
-
@Slim_user71169 我重新表述了这个问题,并附上了一张简图来说明所需的架构。谢谢
-
从描述看来,您的 DatabaseService 应该改为 ContentProvider - 然后您可以使用 ContentObservers 和其他现有 API,而不是尝试重新发明轮子
-
广播接收器或 ResultReceiver 将是实现这一目标的最佳选择
标签: android android-activity android-service localbroadcastmanager