我一直试图在我正在处理的Android应用程序中找出异步i / o的问题。
此应用程序需要从Microsoft Dynamics CRM的一系列表中下载数据。
一旦数据停止,它必须对数据执行一系列操作以填写某些表格。
我的问题是我必须等待下载完成才能开始更新过程。
如果我在代码中添加任何形式的等待,它似乎无限期地阻塞并且永远不会执行回调。
我尝试使用AtomicBooleans,AtomicIntegers和CountDownLatchs的方法没有成功。
以下是使用AtomicInteger的示例。
final CountDownLatch latch = new CountDownLatch(1);
OrganizationServiceProxy orgService;
orgService = new OrganizationServiceProxy(Constant.ENDPOINT, CRMLogin.getRequestInterceptor());
ColumnSet columnSet = new ColumnSet();
columnSet.AddColumns(AccountEntry.FETCH_COLS);
orgService.Retrieve(AccountEntry.ENTITY, UUID.fromString(accountid), columnSet, new Callback<Entity>() {
@Override
public void success(Entity entity, Response response) {
Account account = new Account();
//Load the existing fields for the account
account.load(index);
String activityid = account.getValue(AccountEntry.ACTIVITY_ID);
String recordid = account.getValue(AccountEntry.RECORD_ID);
String name = account.getValue(AccountEntry.ACCOUNT_NAME);
//Overload the fields for the account
account.load(entity);
//Reset overloaded fields on the account.
account.setValue(AccountEntry.ACTIVITY_ID, activityid);
account.setValue(AccountEntry.RECORD_ID, recordid);
account.setValue(AccountEntry.ACCOUNT_NAME, name);
//overwrite the record in the database.
account.setValue(AccountEntry.SYNCED, "1");
account.update();
Log.d("pullAccount>>>", accountid + " " + "pulled.");
latch.countDown();
}
@Override
public void failure(RetrofitError error) {
Log.d("pullAccount>>>", accountid + " " + error.getMessage());
latch.countDown();
}
});
try{
latch.await(); //THIS BLOCKS FOREVER AND EVER
}
catch (Exception e){
}
值得注意的是CallBack是使用Retrofit实现的。
非常感谢任何指导。
谢谢。
答案 0 :(得分:0)
看看AsyncTask
它会以Android优化的方式处理您想要的内容。这里有示例用法
http://developer.android.com/reference/android/os/AsyncTask.html
编辑:
我有点把它扔在一起,让我知道它是否像你期望的那样工作
public class AsyncOrganizationService extends AsyncTask<Void, Void, Entity> {
@Override
protected Entity doInBackground(Void... params) {
final CountDownLatch blocker = new CountDownLatch(1);
OrganizationServiceProxy orgService;
orgService = new OrganizationServiceProxy(Constant.ENDPOINT, CRMLogin.getRequestInterceptor());
ColumnSet columnSet = new ColumnSet();
columnSet.AddColumns(AccountEntry.FETCH_COLS);
final SettableFuture<Entity> result = SettableFuture.create();
orgService.Retrieve(AccountEntry.ENTITY, UUID.fromString(accountid), columnSet, new SortedList.Callback<Entity>() {
@Override
public void success(Entity entity, HttpHelper.Response response) {
result.set(entity);
blocker.countDown();
}
});
try {
blocker.await();
return result.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
protected void onPostExecute(Entity entity) {
Account account = new Account();
//Load the existing fields for the account
account.load(index);
String activityid = account.getValue(AccountEntry.ACTIVITY_ID);
String recordid = account.getValue(AccountEntry.RECORD_ID);
String name = account.getValue(AccountEntry.ACCOUNT_NAME);
//Overload the fields for the account
account.load(entity);
//Reset overloaded fields on the account.
account.setValue(AccountEntry.ACTIVITY_ID, activityid);
account.setValue(AccountEntry.RECORD_ID, recordid);
account.setValue(AccountEntry.ACCOUNT_NAME, name);
//overwrite the record in the database.
account.setValue(AccountEntry.SYNCED, "1");
account.update();
Log.d("pullAccount>>>", accountid + " " + "pulled.");
}
我正在使用Guava的SettableFuture
类(http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/SettableFuture.html)。番石榴是一个非常棒的图书馆 - 如果你不使用它,你应该考虑这样做。否则,你可以快速鞭打什么