通过使用Android Studio,我需要设计一个可从网站读取数据的移动应用程序
,并每分钟刷新一次数据。我面临的问题是,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可以很好地替代它。
我只需要找出可能需要对代码进行哪些更改,以便多次从任何给定的固定网站读取数据,例如,每隔一定时间刷新一次。
答案 0 :(得分:1)
最简单的方法是为每次服务器调用创建一个不同的GetMethodDemo
实例。为此,您需要从活动类中删除asyncTask
字段,并将updateHTML()
方法更改为如下所示:
private void updateHTML() {
GetMethodDemo asyncTask = new GetMethodDemo();
asyncTask.execute(website);
}
我只想提及,使用计时器和异步任务来实现您的目标还有其他选择。您可以使用WorkManager
+ Worker
,RxJava之类的东西。我建议您在使代码正常工作之后,看看其中的一些内容。