AsyncTasks之后的变量丢失,完全在onPostExecute()

时间:2015-11-25 15:43:48

标签: android android-asynctask

在我的活动中,我致电getAllDisponibilita()并覆盖onResult()onError(),以便在执行任务后制作任何内容。我声明了一个变量int a=0外部方法,我在方法中增加它。如果我在onResult()中打印变量,则值会增加,但如果我在onResult()之外打印变量,则值为0.为什么?

这是getAllDisponibilita():"数据访问对象"我用来从数据库中获取数据的方法,这个方法在DisponibilitaDao类中。

public static void getAllDisponibilita(  final List<JSONObject> jsonList,
                                         final OnRestApiResultListener onRestApiResultListener)  {

    new AsyncTask<Void, Void, Integer>() {

        private String errorMessage = null;

        @Override
        protected Integer doInBackground(Void... voids) {
            Log.d("LOL", "Get All Disponibilita...");
            RestApiResource disponibilitaResource = new RestApiResource() {
                @Override
                public String getResourcePath() { return "disponibilita.json"; }
                @Override
                public String getResourceID() { return ""; }
            };

            int rows = 0;
            RestApiParam params[] = {  };
            RestApiClient client = new RestApiClient();
            try {
                JSONArray array = client.get(disponibilitaResource, params, true);
                for(int i = 0; i < array.length(); i++){
                    jsonList.add(array.getJSONObject(i));
                }
                rows = 1;
            } catch ( Exception e ) {
                errorMessage = e.getMessage();
                e.printStackTrace();
            }
            return rows;
        }

        @Override
        protected void onPostExecute(Integer rows) {
            super.onPostExecute(rows);
            if ( errorMessage != null )
                onRestApiResultListener.onError(errorMessage);
            else
                onRestApiResultListener.onResult(rows);
        }
    }.execute();
}

这是我的活动

int a =0;
DisponibilitaDao.getAllDisponibilita(listDisponibilita, new OnRestApiResultListener() {
        @Override
        public void onResult(Integer result) {
         a++;
         //IF HERE I PRINT "a" IT IS INCREASED
        }

        @Override
        public void onError(String message) {
            Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG).show();
        }
    });
           //IF HERE I PRINT "a" IT IS 0

1 个答案:

答案 0 :(得分:1)

调用getAllDisponibilita将启动AsyncTask,这是一个与主ui线程并行运行的独立线程。主要的ui线程(调用getAllDisponibilita的线程)将继续使用&#34; // IF HERE I PRINT&#34; a&#34;它是0&#34;代码,而AsyncTask线程处理doInBackground然后onPostExecute(后者再次在ui线程上)。

由于执行AsyncTask代码需要一些时间,因此当你在主ui线程中打印它的值时,很可能还没有增加(例如,如果竞争条件......)。这就是异步处理的本质。没有其他方法可以确保a增加而不是在onResult方法中读取它。

如果有两个AsyncTasks将其结果放在HashMap中,并且您需要等待两个AsyncTasks在处理结果之前完成,那么这将被视为一个连接(另请参阅http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html)。

在这种情况下,我只是创建一个方法来检查getAllDisponibilita和getAllRichieste是否都已终止,如果是,则根据两个结果处理您要处理的任何代码。如果结果不可用,却什么都不做。您可以从两个onResult方法中调用此方法,并且必须进行同步。这些方面的东西:

private boolean mResultsProcessed;

mResultsProcessed = false;

getAllDisponibilita(listDisponibilita, new OnRestApiResultListener() {
        @Override
        public void onResult(Integer result) {
            checkResult();
        }
    });

getAllRichieste(xyz, new OnRestApiResultListener() {
        @Override
        public void onResult(Integer result) {
            checkResult();
        }
    });

private synchronized void checkResult() {
    if (! mResultsProcessed && hasAllDisponibilitaResults() && hasAllRichiesteResult()) {
       // do whatever you need to do
         mResultsProcessed = true;
    }
}