Java 如何让异步任务在Android中完成
我正在开发一个应用程序,它从网络检索数据,将数据存储到设备,然后读取数据。 问题是,我在异步任务中获取数据。。我的应用程序在试图向用户显示数据之前不允许任务完成。。 我尝试过task.get(),但没有结果(它就停在那里) 我的任务是:Java 如何让异步任务在Android中完成,java,android,android-asynctask,Java,Android,Android Asynctask,我正在开发一个应用程序,它从网络检索数据,将数据存储到设备,然后读取数据。 问题是,我在异步任务中获取数据。。我的应用程序在试图向用户显示数据之前不允许任务完成。。 我尝试过task.get(),但没有结果(它就停在那里) 我的任务是: public GetOptionsTask(XMLPortalGetOptions request) { super(request); } protected void onCancelled(){ // TOD
public GetOptionsTask(XMLPortalGetOptions request) {
super(request);
}
protected void onCancelled(){
// TODO afficher message pas d'options sur le disque
}
@Override
public void handleError(Transaction transaction) {
// TODO afficher message pas d'options sur le disque
}
@Override
public void handleSuccess(Transaction transaction) {
saveOptions(transaction.getResponse());
request = null;
Log.d(OptionsManager.class.getName(), this.getStatus().toString());
}
此任务是自定义异步任务的一个实例:
protected BaseXMLTransaction request;
public abstract void handleError(Transaction transaction);
public abstract void handleSuccess(Transaction transaction);
public TransactionTask(BaseXMLTransaction request){
this.request = request;
}
@Override
protected Void doInBackground(Void... params) {
try {
Log.i(TransactionTask.class.getName(), "Doing in background");
SocketHandler.sendTransaction(this, request.getRequest());
} catch (SocketHandlerNotConfiguredException e) {
Log.e(TransactionTask.class.getName(), "SocketHandler's parameters were not set.");
}
return null;
}
@Override
public void transactionResult(Transaction transaction) {
switch (transaction.getCode()) {
case ERROR:
Log.e(TransactionTask.class.getName(), "ERROR !!!");
handleError(transaction);
break;
case NO_CLIENT:
Log.e(TransactionTask.class.getName(), "No Client Error");
handleError(transaction);
break;
case NO_SERVER:
Log.e(TransactionTask.class.getName(), "No Server Error");
handleError(transaction);
break;
case OLD_VERSION:
Log.e(TransactionTask.class.getName(), "Old Version");
handleError(transaction);
break;
case TIMEOUT:
Log.e(TransactionTask.class.getName(), "Transaction Timeout");
handleError(transaction);
break;
case SUCCESS:
Log.i(TransactionTask.class.getName(), "Transaction Success");
handleSuccess(transaction);
}
}
我真的不知道该怎么办。。。Execute变为fast,get不做任何事情,因为我猜我不会返回任何东西
onPostExecute(Result),在后台计算完成后在UI线程上调用。背景计算的结果作为参数传递到此步骤
我使用一个接口作为委托来完成这项工作。以下是一个例子: 在我的主要活动中,我有一个onClick侦听器来触发异步调用,还有一个侦听器在调用完成后进行处理
private void enableLocationButton(){
locationButton = (Button) findViewById(R.id.locationButton);
locationButton.setEnabled(true);
locationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, selectLocationActivity.class);
intent.putExtra("serverURL",server.getWebServerAddressField());
startActivityForResult(intent, 200);
}
});
}
@Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
if(resultCode == RESULT_OK) {
switch (requestCode){
case 100:
processServerResponse((PmsWebServer) data.getBundleExtra("server").get("server"));
break;
case 200:
processLocationResponse((PmsDataSource)data.getBundleExtra("location").get("location"));
default:processError();
}
}else{
processError();
}
}
在selectLocationActivity的某个地方,我有一个对异步调用的调用和一些处理响应的东西,请注意,这个类实现了一个异步调用中使用的接口
public class selectLocationActivity extends ListActivity implements SoapServiceInterface{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_select);
chosenServer = this.removeURLHeader(getIntent().getStringExtra("serverURL"));
this.retrieveLocationOptionsByServer(chosenServer);
}
private void retrieveLocationOptionsByServer(String server) {
Map<String,Object> parms = new HashMap<String,Object>();
parms.put(WEB_SERVER_NAME,server);
SoapServiceObject service = new SoapServiceObject(Services.SERVICE_DETAILS,parms);
callTheService(service);
}
private void callTheService(SoapServiceObject service){
SoapServiceHelper helper = new SoapServiceHelper();
helper.delegate = thisActivity;
helper.execute(service);
}
@Override
public void serviceCallComplete(SoapObject response){
this.createClickableListOnScreen(response);
}
//...more code...//
}
我知道我正在直接从结果向屏幕显示某些内容,只需使用“保存并读取”命令将该部分分为几部分;) 该任务的一个特点是,它将内容保存到一个单例中。我设法使用onResume()上的singleton中保存的网络信息来调用这些方法。当线程结束时,它进入onResume,一切正常 这是用户每次使用您的应用程序时都需要执行的操作,还是数据下载到设备并保存一次?保存一次,除非用户要求应用程序重新加载来自网络的数据,或者数据过期(一周后),您所指的确切含义是什么“我的应用程序在尝试向用户显示数据之前不允许任务完成”?是否在onPostExecute()中触发gui更新,如@Matias Eloriaga answer所示。您可以添加onPostExecute()的代码和gui更新代码吗?方法
saveOptions
的作用是什么?您如何保存选项?saveOptions()只是将数据写入设备上的xml文件中。这只是一个示例,重点是您需要重写onPostExecute,该方法在UI线程中运行,并作为参数接收asyncTask的响应(doInBackground方法)仅供参考,这只是一个帮助我的队友了解异步任务如何工作的实验,我知道我不应该打印出异常
new DownloadFilesTask().execute(url1, url2, url3);
private void enableLocationButton(){
locationButton = (Button) findViewById(R.id.locationButton);
locationButton.setEnabled(true);
locationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, selectLocationActivity.class);
intent.putExtra("serverURL",server.getWebServerAddressField());
startActivityForResult(intent, 200);
}
});
}
@Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
if(resultCode == RESULT_OK) {
switch (requestCode){
case 100:
processServerResponse((PmsWebServer) data.getBundleExtra("server").get("server"));
break;
case 200:
processLocationResponse((PmsDataSource)data.getBundleExtra("location").get("location"));
default:processError();
}
}else{
processError();
}
}
public class selectLocationActivity extends ListActivity implements SoapServiceInterface{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_select);
chosenServer = this.removeURLHeader(getIntent().getStringExtra("serverURL"));
this.retrieveLocationOptionsByServer(chosenServer);
}
private void retrieveLocationOptionsByServer(String server) {
Map<String,Object> parms = new HashMap<String,Object>();
parms.put(WEB_SERVER_NAME,server);
SoapServiceObject service = new SoapServiceObject(Services.SERVICE_DETAILS,parms);
callTheService(service);
}
private void callTheService(SoapServiceObject service){
SoapServiceHelper helper = new SoapServiceHelper();
helper.delegate = thisActivity;
helper.execute(service);
}
@Override
public void serviceCallComplete(SoapObject response){
this.createClickableListOnScreen(response);
}
//...more code...//
}
public class SoapServiceHelper extends AsyncTask<SoapServiceObject, Void, SoapObject>{
public SoapServiceInterface delegate = null;
private Integer RETRY_COUNT = 0;
private final Integer MAX_RETRY_COUNT = 2;
protected SoapObject doInBackground(SoapServiceObject... args){
SoapServiceObject service = args[0];
try{
service.callTheService();
}catch(Exception e){
System.out.println("An error occurred calling the service\n" + e.getMessage());
}
return service.getResponse();
//return callDateTimeService();
}
protected void onPostExecute(SoapObject result){
delegate.serviceCallComplete((SoapObject)(result.getProperty(0)));
}
}
public interface SoapServiceInterface {
public void serviceCallComplete(SoapObject response);
}