AsyncTask只能执行一次

时间:2018-12-03 09:36:56

标签: android rest android-asynctask get illegalstateexception

通过使用Android Studio,我需要设计一个可从网站读取数据的移动应用程序

  

http://sspapi-dev.samsungrs.com/health

,并每分钟刷新一次数据。我面临的问题是,Android中的AsyncTask只能执行一次,因此,下次我尝试刷新页面并再次从网站读取数据时,会收到以下错误消息。

  

2018-12-03 14:48:21.308 5065-5065 / com.samsung.asynctaskexample   E / AndroidRuntime:致命异常:main       流程:com.samsung.asynctaskexample,PID:5065       java.lang.IllegalStateException:无法执行任务:该任务已经执行(一个任务只能执行一次)           在android.os.AsyncTask.executeOnExecutor(AsyncTask.java:605)           在android.os.AsyncTask.execute(AsyncTask.java:560)           在com.samsung.asynctaskexample.MainActivity.updateHTML(MainActivity.java:45)           在com.samsung.asynctaskexample.MainActivity.access $ 000(MainActivity.java:10)           在com.samsung.asynctaskexample.MainActivity $ 1 $ 1.run(MainActivity.java:37)           在android.os.Handler.handleCallback(Handler.java:751)           在android.os.Handler.dispatchMessage(Handler.java:95)           在android.os.Looper.loop(Looper.java:154)           在android.app.ActivityThread.main(ActivityThread.java:6682)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1520)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

有哪些不同的方法可以修复此错误消息? 这是我的代码。

MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements AsyncResponse {
    GetMethodDemo asyncTask = new GetMethodDemo();
    TextView t1;
    String website = "http://sspapi-dev.samsungrs.com/health";

    private Timer autoUpdate;
    int refresh_interval = 60000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        t1 = findViewById(R.id.textview1);

        asyncTask.delegate = this;
    }

    @Override
    public void onResume() {
        super.onResume();
        autoUpdate = new Timer();
        autoUpdate.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        updateHTML();
                    }
                });
            }
        }, 0, refresh_interval);
    }

    private void updateHTML() {
        asyncTask.execute(website);
    }

    @Override
    public void onPause() {
        autoUpdate.cancel();
        super.onPause();
    }

    @Override
    public void processFinish(String output){
        t1.setText(output);
    }
}

JsonHelper.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class JsonHelper{

    HttpURLConnection connection;
    String data;

    public String getdatafromurl(String url){
        try{
            URL url1 = new URL(url);

            connection = (HttpURLConnection) url1.openConnection();
            connection.connect();
            InputStream inputStream = connection.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";
            StringBuffer buffer = new StringBuffer();

            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            String result = buffer.toString();
            return result;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }
}

GetMethodDemo.java

import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class GetMethodDemo extends AsyncTask<String, Void, String> {
    public AsyncResponse delegate = null;
    String server_response;

    @Override
    protected String doInBackground(String... strings) {

        URL url;
        HttpURLConnection urlConnection = null;

        try {
            url = new URL(strings[0]);
            urlConnection = (HttpURLConnection) url.openConnection();

            int responseCode = urlConnection.getResponseCode();

            if(responseCode == HttpURLConnection.HTTP_OK){
                server_response = readStream(urlConnection.getInputStream());
            }

            JsonHelper jsonhelper = new JsonHelper();
            String data = jsonhelper.getdatafromurl(strings[0]);

            return data;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

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

// Converting InputStream to String

    private String readStream(InputStream in) {
        BufferedReader reader = null;
        StringBuffer response = new StringBuffer();
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return response.toString();
    }
}

AsyncResponse.java

public interface AsyncResponse {
    void processFinish(String output);
}

顺便说一句,利用

while(true) {
            asyncTask.execute(website);

            try
            {
                Thread.sleep(refresh_interval);
            }
            catch(InterruptedException ex)
            {
                break;
            }
        }
我最初尝试的

似乎不是一个好主意,因为Thread.sleep函数会干扰其他Android应用程序甚至整个Android操作系统的性能。我发现以上述方法使用Timer可以很好地替代它。

我只需要找出可能需要对代码进行哪些更改,以便多次从任何给定的固定网站读取数据,例如,每隔一定时间刷新一次。

1 个答案:

答案 0 :(得分:1)

最简单的方法是为每次服务器调用创建一个不同的GetMethodDemo实例。为此,您需要从活动类中删除asyncTask字段,并将updateHTML()方法更改为如下所示:

private void updateHTML() {
    GetMethodDemo asyncTask = new GetMethodDemo();
    asyncTask.execute(website);
}

我只想提及,使用计时器和异步任务来实现您的目标还有其他选择。您可以使用WorkManager + Worker,RxJava之类的东西。我建议您在使代码正常工作之后,看看其中的一些内容。