java - 使用 AsyncTask,但遇到意外行为

标签 java android multithreading android-asynctask

请引用下面的代码,不断调用一个新的AsyncTaskAsyncTask 的用途是发出 HTTP 请求,并更新字符串 result

package room.temperature;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class RoomTemperatureActivity extends Activity {

    String result = null;
    StringBuilder sb=null;

    TextView TemperatureText, DateText;
    ArrayList<NameValuePair> nameValuePairs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TemperatureText = (TextView) findViewById(R.id.temperature); 
        DateText = (TextView) findViewById(R.id.date); 
        nameValuePairs = new ArrayList<NameValuePair>();

        for (int i = 0; i < 10; i++) {          
            RefreshValuesTask task = new RefreshValuesTask();
            task.execute("");
        }
    }

    // The definition of our task class
    private class RefreshValuesTask extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params) {
            InputStream is = null;

            try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://mywebsite.com/roomtemp/tempscript.php");
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
            }

            catch(Exception e)  {
                Log.e("log_tag", "Error in http connection" + e.toString());
            }

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                sb = new StringBuilder();
                sb.append(reader.readLine());
                is.close();
                result=sb.toString();
            }

            catch(Exception e)  {
                Log.e("log_tag", "Error converting result " + e.toString());
            }

            return result;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            //System.out.println(result);
            setValues(result);
        }
    }

    public void setValues(String resultValue) {
        System.out.println(resultValue);
        String[] values = resultValue.split("&");

        TemperatureText.setText(values[0]);
        DateText.setText(values[1]);
    }
}

我遇到的问题在某种程度上与AsyncTask或函数setValues()有关,但我不确定如何。本质上,我希望每次调用 AsyncTask 都能运行,最终在无限的 while 循环中运行,并更新 TextView 字段,就像我在 setValues 中尝试的那样>。我从昨天开始就尝试过询问question由此产生了这段代码,供引用。

哦,是的,我确实尝试使用 AsyncTask get() 方法,但这也不起作用,因为我发现它实际上是一个同步调用,并使 AsyncTask 的全部意义变得无用。

最佳答案

使用 publishProgress()onProgressUpdate() 方法来发布进度,同时在 doInBackground() 方法中执行某些任务。

因此将您的代码更改为以下内容:

package room.temperature;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class RoomTemperatureActivity extends Activity {

    String result = null;
    StringBuilder sb=null;

    TextView TemperatureText, DateText;
    ArrayList<NameValuePair> nameValuePairs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TemperatureText = (TextView) findViewById(R.id.temperature); 
        DateText = (TextView) findViewById(R.id.date); 
        nameValuePairs = new ArrayList<NameValuePair>();

         RefreshValuesTask task = new RefreshValuesTask();
         task.execute("");
    }

    // The definition of our task class
    private class RefreshValuesTask extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params) {
            InputStream is = null;
            for (int i = 0; i < 10; i++) {          

            try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://mywebsite.com/roomtemp/tempscript.php");
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
            }

            catch(Exception e)  {
                Log.e("log_tag", "Error in http connection" + e.toString());
            }

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                sb = new StringBuilder();
                sb.append(reader.readLine());
                is.close();
                result=sb.toString();
                publishProgress(result);
            }

            catch(Exception e)  {
                Log.e("log_tag", "Error converting result " + e.toString());
             }
            }
            return result;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            setValues(values);
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            //System.out.println(result);
            setValues(result);
        }


    }

    public void setValues(String resultValue) {
        System.out.println(resultValue);
        String[] values = resultValue.split("&");

        TemperatureText.setText(values[0]);
        DateText.setText(values[1]);
    }
}

关于java - 使用 AsyncTask,但遇到意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097156/

相关文章:

Java/Android Edittext.gettext().toString 不工作

java - 类型类型转换一个数字加倍

c++ - 中断主线程并要求它做一些事情

android - 有没有办法使用 Android 中的 DownloadManager 通过 LAN 下载?

java - hibernate 保存时发生 StackOverflowError

java - 包装器的 parseXXX() 用于签名二进制误解

java - 使用 Java-8 获取最高有效十进制数字

java - 如何连接任意两个特定线程?

python - 在线程中打印不适用于python 3

java - log4j.properties 到 log4j2 log2.xml