Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让异步任务在Android中完成_Java_Android_Android Asynctask - Fatal编程技术网

Java 如何让异步任务在Android中完成

Java 如何让异步任务在Android中完成,java,android,android-asynctask,Java,Android,Android Asynctask,我正在开发一个应用程序,它从网络检索数据,将数据存储到设备,然后读取数据。 问题是,我在异步任务中获取数据。。我的应用程序在试图向用户显示数据之前不允许任务完成。。 我尝试过task.get(),但没有结果(它就停在那里) 我的任务是: public GetOptionsTask(XMLPortalGetOptions request) { super(request); } protected void onCancelled(){ // TOD

我正在开发一个应用程序,它从网络检索数据,将数据存储到设备,然后读取数据。 问题是,我在异步任务中获取数据。。我的应用程序在试图向用户显示数据之前不允许任务完成。。 我尝试过task.get(),但没有结果(它就停在那里)

我的任务是:

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);
}