-1

我有一个问题,我试图从内部类的doInBackground方法访问外部类的私有变量。AsyncTask这里有完整的代码。

public class MessageHandler {
private Contact receiver;
private String senderFacebookId;
private String message;
private final String TAG = "MessageHandler";
private Context context;
boolean sentResult;

public MessageHandler(Contact receiver, String senderFacebookId, String message, Context context) {
    this.receiver = receiver;
    this.senderFacebookId = senderFacebookId;
    this.message = message;
    this.context=context;
    this.sentResult = false;
}

public void send(){
    Log.i(TAG, "Sending message to " + receiver.getName() + " receiver id: " + receiver.getFacebook_id() + " sender id: " + senderFacebookId + " message: " + message);

    new SenderAsync().execute(senderFacebookId,message, receiver.getFacebook_id());
    if(this.sentResult==true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();

    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}



private class SenderAsync extends AsyncTask<String,String,String> {

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();

        try {
            List<NameValuePair> parameter = new ArrayList<>(1);
            parameter.add(new BasicNameValuePair("regId", "empty"));
            parameter.add(new BasicNameValuePair("sender_id", params[0]));
            parameter.add(new BasicNameValuePair("receiver_facebook_id", params[2]));

            parameter.add(new BasicNameValuePair("message", params[1]));

            String paramString = URLEncodedUtils.format(parameter, "utf-8");
            HttpGet get = new HttpGet(ProfileFragment.SERVER_URL_SEND_MESSAGE+"?"+paramString);

            Log.i(TAG, paramString);
            HttpResponse resp = client.execute(get);
            System.out.println("SREVER RESPONSE " + resp.getStatusLine().getStatusCode());

            //THIS IS THE VARIABLE THAT I WANT TO ACCESS
            if(resp.getStatusLine().getStatusCode()==200){
                MessageHandler.this.sentResult = true;
            }



        } catch (IOException e) {

            Log.i(TAG,"Error :" + e.getMessage());
        }
        return null;
    }
}

}

我试图访问的变量是布尔变量sentResult。我还打印出始终为 200 的服务器的响应。即使我删除了 if 条件并将其设置为无论如何都为真,看起来那行代码永远不会执行并且变量没有被访问,所以它总是错误的。

4

4 回答 4

2

异步任务的全部意义在于它是异步的。如果您执行一项任务,您将不会在下一行代码中获得结果。为了评估结果,您应该使用onPostExecute回调方法。

@Override
protected void onPostExecute(String s) {
    if(sentResult==true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();
    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}

此外,如果您要更改方法签名,您甚至不需要外部变量。

private class SenderAsync extends AsyncTask<String,String,Boolean> {

@Override
protected void onPostExecute(Boolean sent) {
    if(sent == true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();
    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}

@Override
protected Boolean doInBackground(String... params) {
    try {
        ...
        if (resp.getStatusLine().getStatusCode() == 200) {
            return true;
        }
    }
    catch (IOException e) {

    }

    return false;
}
于 2015-08-08T21:00:18.793 回答
0

为 SenderAsync 创建构造函数;

公共 SenderAsync(上下文上下文,字符串 senderId,字符串 msg,联系接收者)

这样称呼它;

新的 SenderAsync(senderFacebookId,message,receiver.getFacebook_id()).execute();

你需要在 onPostExecute 中得到你的结果。void onPostExecute(String returnedValue) { // 在这里运行你想要的 if 语句 }

于 2015-08-08T20:55:34.477 回答
0

sentResult在您告诉 AsyncTask 完成其工作后,您正在尝试验证。AsyncTask 在单独的线程上并行执行它必须执行的操作。所以在它完成之前,sentResult是不变的。

我的建议是将您的 Toast 逻辑放在 onPostExecute 中。

于 2015-08-08T21:01:03.340 回答
0

您错误地使用了 AsyncTask。AsyncTask 应该在onPostExecute()中返回结果,并且您的 UI 应该有一个单独的方法onPostExecute()调用(因此是异步名称)。对于您要完成的工作,您应该这样做:

public void send() {
    new SenderAsync().execute(senderFacebookId,message, receiver.getFacebook_id());
}

public void processResult(boolean result) {
  String resultMsg = result ? "Message Sent" : "ERROR: Message not Sent";
  Toast.makeText(this.context, resultMsg, Toast.LENGTH_LONG).show();
}

private class SenderAsync extends AsyncTask<String, String, Boolean> {
  ...
  @Override
    protected String doInBackground(String... params) {
      ...
      try {
        ...
        return (resp.getStatusLine().getStatusCode() == 200)
      }
      ...
      return false;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        processResult(result);
    }
}
于 2015-08-08T21:14:56.440 回答