我想从片段中运行onDestroy()的长操作任务。我的目标是呼叫网络呼叫以删除一些数据,以防用户通过从最近的应用程序刷它来关闭应用程序。我希望在调用onDestroy()时启动一个intent。
此刻,每当我尝试启动意图时,在我有机会操作调用之前我会松开上下文,因为onDestroy()已经杀死了我的应用程序。
我不想使用这个选项:Performing long running operation in onDestroy因为运行这样的线程不是正确的做法,而且看起来像是一个危险的黑客。
从活动的onDestroy()调用操作会导致相同的错误。
当然,我不希望在ui线程上做任何工作,并且“推迟”onDestroy()直到我的操作完成。
为了清除,当getContext()不为null时,到达SomeService类时,上下文已经为空,因为发送intent是异步操作。
@Override
public void onDestroy() {
Intent intent = new Intent(getContext(), SomeService.class);
getContext().startService(intent);
super.onDestroy();
}
答案 0 :(得分:1)
我建议在onCreate()
Activity
说Service
之前启动并绑定服务,然后通过绑定服务,您可以轻松启动放置在//somewhere in onCreate()
myServiceIntent = new Intent(this.getApplicationContext(), MyService.class);
context.startService(myServiceIntent);
context.bindService(myServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
中的清理工具,即您应该将服务开始和清理开始分开。
像:
onDestroy()
然后在public void onDestroy() {
myService.cleanup();
super.onDestroy();
}
- (void) fetchContacts
{
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can use contacts" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init]; [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(@"error = %@", fetchError);
}
// you can now do something with the list of contacts, for example, to show the names
CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
for (CNContact *contact in contacts) {
if (!_contacts) {
_contacts = [[NSMutableArray alloc] init];
}
NSString *string = [formatter stringFromContact:contact];
NSLog(@"contact = %@", string);
[_contacts addObject:string];
}
[_contactatableview reloadData];
}];
}
详细了解service binding
答案 1 :(得分:0)