试图从OnPostExecute中获取一个值

时间:2016-02-17 16:55:27

标签: java android android-asynctask

我整天都在想着什么。

问题是,我有一个AsyncTask,它返回一个User对象及其所有属性。我知道我必须从doInBackground方法返回并在OnPostExecute中接收以处理我的数据。事实是,我想从AsyncTask方法中提取该用户,因为我必须在我的主线程中使用它。 我的AsyncTask类放在MainActivity.class中。

我听说过使用接口来获取我的价值,但我无法理解这样做的方法。

 public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
    RequestHandler rh = new RequestHandler(); //this is the class i use to do de server conection
    User user;
    User ret_user;


    public FetchUserDataAsyncTask(User user){
        this.user  = user;
    }


    @Override
    protected void onPostExecute(User user) {
        super.onPostExecute(user);

   //I WANT THIS USER IN MY MAIN THREAD, TO WORK WITH ITS ATTRIBUTES

    }



    @Override
    protected User doInBackground(Void... params) {
        try {
            HashMap<String, String> dataToSend = new HashMap<>();
            dataToSend.put("username", user.username);
            dataToSend.put("password", user.password);
            ret_user = rh.sendGetRequest("myadresstophp.php", dataToSend);

        } catch (Exception e) {
            e.printStackTrace();
        }

 return ret_user;
 }

和通话(当用户按下登录按钮时),上面几行。

 new FetchUserDataAsyncTask(userk).execute();

我希望能做到这样的事情:(我知道不是这样做的)

User user = new FetchUserDataAsyncTask(userk).execute();

谢谢大家,祝你有愉快的一天!

5 个答案:

答案 0 :(得分:2)

首先在项目中声明一个具有所需函数的接口,然后在(AsyncTask)调用类中实现该接口,然后在AsyncTask中声明一个Interface对象。按如下方式创建AsyncTask的构造函数:

public FetchUserDataAsyncTask(User user,InterfaceClass object){
    this.user  = user;
    this.interfaceObject=object;
}

然后在onPostExecute中执行以下操作:

@Override
protected void onPostExecute(User user) {
    super.onPostExecute(user);
    interfaceObject.function(user);  //call the function of the calling class

}

答案 1 :(得分:1)

您可以创建一个接口,将其传递给AsyncTask(在构造函数中),然后在onPostExecute()中调用方法

例如:

您的界面:

public interface OnTaskCompleted{ 
    void onTaskCompleted(); 
}

您的活动:

public class YourActivity implements OnTaskCompleted{ 
    // your Activity 
}

你的AsyncTask:

public class YourTask extends AsyncTask<Object,Object,Object>{ 
    //change Object to required type 

    private OnTaskCompleted listener;

    public YourTask(OnTaskCompleted    
    listener){ 
        this.listener=listener; 
    } // required methods 

    protected void onPostExecute(Object    
    o){
       // your stuff 
       listener.onTaskCompleted(); 
    } 
}

答案 2 :(得分:0)

默认情况下,

onPostExecute在UI线程上运行(主线程)。在onPostExecute

的主线程上做你需要做的事情

我建议您从下面提供的链接中阅读更多内容,以便更好地了解AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html

答案 3 :(得分:0)

我不确定你的意思是&#34;主线&#34;。如果您的意思是&#34; UI Thread&#34;,这是用于在您的应用中执行的主要线程,那么Shashank的回复是正确的。

但是,我怀疑从问题的上下文中你实际上意味着你希望结果返回到启动AsyncTask的代码。让我们称之为&#34;调用对象&#34;在这种情况下,我要做的是在你的调用对象中定义一个回调,它的唯一目的是接收这个AsyncTank的结果。你可以称之为onUserDataFetched(User user)

因此,要使用Interfaces执行此操作,您可以定义包含单个方法的接口:

public interface FetchUserDataListener {
    public void onUserDataFetched(User user);
}

然后确保您的InvokingObject实现了该接口,并在实例化时将您的InvokingObject(实现FetchUserData,因此可以认为是该对象类型)传递给AsyncTask。

因此,您调用对象代码将如下所示:

public class InvokingObject implements FetchUserData {
    public void someMethodToInvokeFetchUserData() {
        //....
        new FetchUserDataAsyncTask(userk, this).execute();
        //....
    }

    @Override
    public void onUserDataFetched(User user) {
         //Compare the result to the data in your invoking object
    }
}

然后在构造它时将该回调传递给AsyncTask: 您的AsyncTask代码如下所示:

public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User>         {
  FetchUserDataListener mFetchUserDataListener;

  public FetchUserDataAsyncTask(User user, FetchUserDataListener listner){
      this.user  = user;
      mFetchUserDataListener = listener
  }

  //...
  @Override
  protected void onPostExecute(User user) {
      super.onPostExecute(user);
      listener.onUserDataFetched(user)
  }
  //...

 }

答案 4 :(得分:0)

在这里,一般来说,它是如何工作的。这基于this answer并已修改为特定于您现有的代码。基本上根据用户输入的内容分配您的成员变量,并将该值与您从服务器获得的值进行比较:

public class MyClass extends Activity {

  //member variable for the username the user enters:
  User userEnteredUser;

  public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
    RequestHandler rh = new RequestHandler(); //this is the class i use to do de server conection
    User user;
    User ret_user;


    public FetchUserDataAsyncTask(User user){
        this.user  = user;
    }


    @Override
    protected void onPostExecute(User user) {
        super.onPostExecute(user);

   //I WANT THIS USER IN MY MAIN THREAD, TO WORK WITH ITS ATTRIBUTES
       processValue(user);  //added

    }



    @Override
    protected User doInBackground(Void... params) {
        try {
            HashMap<String, String> dataToSend = new HashMap<>();
            dataToSend.put("username", user.username);
            dataToSend.put("password", user.password);
            ret_user = rh.sendGetRequest("myadresstophp.php", dataToSend);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return ret_user;
    }
   }

  private void getValue()
  {
      EditText et = (EditText) findViewById(R.id.username);
      userEnteredUser.username = et.getText().toString(); //something like this.... replace with your syntax
      new FetchUserDataAsyncTask(userEnteredUser).execute();
  }

  private void processValue(User userFromServer) 
  {
    if (userEnteredUser.equals(userFromServer)) {
      //Users match! Yay!
    }
  }
}