2014-10-16 64 views
0

我有一个AsyncTask,我想在此类的 字段中存储一些信息。我有这样的事情:AsynTask字段为空

public class NFCReaderTask extends AsyncTask<Void, Void, Void> { 
    private String Year = null; 
    private String Month = null; 
    private String Day = null; 

    @Override 
    protected void onPreExecute() { 
     // do some stuff 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     // do some stuff 
    } 

    @Override 
    protected void onPostExecute(final Void unused) { 
     // do some stuff 
     // here my fields are filled with all informations 

     log.v("This First", "" + getYear()); 
    } 

    public String getYear() { 
     return Year; 
    } 
    public String getMonth() { 
     return Month; 
    } 
    public String getDay() { 
     return Day; 
    } 
} 

在我的活动我这样做:

public void resolveIntent(Intent intent) { 
    // ... 

    NFCReaderTask startReaderTask = new NFCReaderTask(dataDevice); 
    startReaderTask.execute(); 
    startReaderTask.get(); 

    log.v("This Second", "" + startReaderTask.getYear()); // but this is printed out first 

    // ... 
} 

但值均为空。为什么我的字段在我的onPostExecute方法的最后几行填充了信息 ,但在AsyncTask的.execute() 之后为空?

编辑:

我加了一些日志输出,并注意到了,从我的活动 日志输出我的AsyncTask的日志输出之前打印出来。这是否意味着 AsyncTask#get()不起作用?

+1

你不应该使用get,因为它会等待线程完成执行。您还应该1000%不使用您接受的答案,即运行一个while循环,直到AsyncTask停止运行以延迟执行代码。你应该使用回调。请参阅下面的答案。 – Rarw 2014-10-16 18:06:51

+1

你也不需要也不应该使用getter方法。 AsyncTask异步运行,这意味着它不遵循正常代码的流程。你不知道什么时候会回复答案。因此,获得者是不合适的,因为当你打电话给他们时,很可能没有价值。使用仅在任务完成时触发的回调/接口解决了这个问题。 – Rarw 2014-10-16 18:32:06

回答

0

它们为空,因为至少在提供的代码中,您从不提供它们的值。您需要使用setter方法设置执行前的年,月和日值,或者需要在execute()方法中提供数据作为参数并检索参数。例如:

@Override 
protected Void doInBackground(String...params){ 
    String year = params[0]; 
    String month = params[1]; 
    String day = params[2]; 
} 

如果你的问题是,你是不是从AsyncTask返回值,这是因为AsyncTask并不像一个正常的方法返回值。作为一般规则,您不应该使用get()方法来获取值。相反,请在AsyncTask中定义一个接口,并使用它来回调您的起始活动或片段以及结果。例如:

public interface ReaderTaskCallback{ 
    public void onTaskComplete(String year, String month, String day); 
} 

设置界面,当你加入一个setCallback方法

//In your AsyncTask 
private ReaderTaskCallback mCallback; 

public void setCallback(ReaderTaskCallback callback){ 
    mCallback = callback; 
} 

//In your activity 
NFCReaderTask startReaderTask = new NFCReaderTask(dataDevice); 
startReaderTask.setCallback(new ReaderTaskCallback(){ 

    @Override 
    public void onTaskComplete(String year, String month, String day){ 
     //use results 
    } 

}); 

要得到的结果从任务回来只是调用回调方法时,你的任务是这样完成创建AsyncTask

mCallback.onTaskComplete(year, month, day); 

这些值在准备好后会被传回给您的活动或片段。

+0

问题是我不能在doInBackground中设置值。我必须在onPostExecute中设置它们,所以我不能调用AsyncTask#wait()。 – Mulgard 2014-10-16 18:13:17

+0

你可以调用onPreExecute()中的get方法,或者你可以为asyncTask创建一个构造函数。你也可以在执行时传递一个高级对象,将你的asyncTask改为 danny117 2014-10-16 18:21:18

+0

你是什么意思,你必须在onPostExecute中设置它们?我很困惑。如果您的意思是在任务完成onDoInBackground之前您没有这些值,那么您应该使用我的方法并在您的onPostExecute中调用回调方法。在后台执行工作,将结果返回到onPostExecute或设置该任务的成员值,然后调用回调函数onPostExecute将值返回给您的活动。 – Rarw 2014-10-16 18:29:12

0

你不能从任何地方通过任何日期参数,如果你这样做,你还愿意再需要一个构造函数添加到您的NFCReaderTask类...

public NFCReaderTask(String year, String month, String day) { 
    Year = year; 
    Month = month; 
    Day = day; 
} 

设定日期参数的任务,例如如:

new NFCReaderTask("2014", "10", "16").execute(); 

顺便说一句,如果您的日期值是整数,你不需要沿着将它们作为字符串:

new NFCReaderTask(2014, 10, 16).execute();