AsyncTask может быть выполнен только один раз - PullRequest
0 голосов
/ 03 декабря 2018

Используя Android Studio, мне нужно создать мобильное приложение, которое считывает данные с веб-сайта

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

и обновляет данные каждую минуту.Проблема, с которой я сталкиваюсь, заключается в том, что AsyncTask в Android можно выполнить только один раз, поэтому в следующий раз, когда я пытаюсь обновить страницу и снова прочитать данные с веб-сайта, я получаю следующее сообщение об ошибке.

2018-12-03 14: 48: 21.308 5065-5065 / com.samsung.asynctaskexample E / AndroidRuntime: FATAL EXCEPTION: 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) на андроиде.os.Handler.handleCallback (Handler.java:751) в android.os.Handler.dispatchMessage (Handler.java:95) в android.os.Looper.loop (Looper.java:154) вdroid.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 голосов
/ 03 декабря 2018

Самое простое, что вы можете сделать, - это создать отдельный экземпляр GetMethodDemo для каждого обращения к серверу.Для этого вам нужно удалить поле asyncTask из вашего класса активности и изменить метод updateHTML() на что-то похожее на это:

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

Я просто хочу упомянуть, что есть другиеальтернативы использованию таймеров и асинхронных задач для достижения того, к чему вы стремитесь.Вы можете использовать что-то вроде WorkManager + Worker, RxJava и т. Д. Я советую вам взглянуть на некоторые из них после того, как ваш код заработал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...