By using Android Studio, I need to design a mobile application that reads data from the website
and refreshes the data every minute. The problem I am facing is that AsyncTask in Android can be executed only once, so the next time I try to refresh the page and read data again from the website I am getting the following error message.
2018-12-03 14:48:21.308 5065-5065/com.samsung.asynctaskexample E/AndroidRuntime: FATAL EXCEPTION: main Process: com.samsung.asynctaskexample, PID: 5065 java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once) at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:605) at android.os.AsyncTask.execute(AsyncTask.java:560) at com.samsung.asynctaskexample.MainActivity.updateHTML(MainActivity.java:45) at com.samsung.asynctaskexample.MainActivity.access$000(MainActivity.java:10) at com.samsung.asynctaskexample.MainActivity$1$1.run(MainActivity.java:37) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6682) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
What are the different ways that are available to fix this error message? Here is my code.
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);
}
By the way, making use of
while(true) {
asyncTask.execute(website);
try
{
Thread.sleep(refresh_interval);
}
catch(InterruptedException ex)
{
break;
}
}
which I had first tried out initially, seems to be a bad idea since Thread.sleep function interferes with the performance of the other Android applications and even the overall Android operating system. I found out that making use of Timer in the way that I had described above is a good substitute for it.
Just I need to find out what changes are possible that I need to make to the code in order to read data from any given fixed website more than once, for example, to refresh at certain interval of period of time.