1

Тема: Асинхронна робота потоків(Android/Java)

Привіт!
Як визначити у головному потоці що код в асинхронному потоці вже закінчив свою роботу?
Наприклад:

public class MainActivity extends AppCompatActivity {
    Server server = new Server();
    static TextView info;

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

        info = findViewById(R.id.info);


            new Thread(new Runnable() {
                public void run() {
                    server.download();//створення запиту на сервер у власному класі
                }
            }).start();

        /*
         Якщо створити метод який буде зберігати відповідь сервера і викликати його тут
         
         server.getResult();//метод повертає відповідь сервера
         
         То це поверне null так як сервер ще не встиг відповісти.

         Як тут у головному потоці взнати що настала пора викликати server.getResult() для подальшої обробки
       */


    }

     //якщо використати цей метод то приходиться переводити все у static що викликає перезавантаження пам'яті
    public static void result(ServerInfo si){
         info.setText(si.getInfo);
    }
}


public class Server{
    public String SN = "http://mysait.com";
    public ServerInfo serverInfo;
    
     public void download(){
         Retrofit retrofit = new Retrofit.Builder()
                .baseUrl (SN) 
                .addConverterFactory (GsonConverterFactory.create ())
                .build();

        request = retrofit.create(GetRequest_Interface.class);
        
        Call<ServerInfo> call = request.Info(SN + "/info.php?info=1");
        call.enqueue(new Callback<ServerInfo>() {
            serverInfo;

            @Override
            public void onResponse(@NonNull Call<ServerInfo> call, @NonNull Response<ServerInfo> response) {
                if(response.isSuccessful()){
                    serverInfo = response.body();
                }else{}

                MainActivity.result(serverInfo);//якщо використати цей рядок то потрібно створювати статичний метод в головному потоці
            }

            @Override
            public void onFailure(@NonNull Call<ServerInfo> call, @NonNull Throwable t) { }
        });
    }

    public ServerInfo getResult(){
        ...
        return serverInfo;
    }
}

Це урізаний код з нього викинуто майже все. Залишив лише головне. Проблему у тому що якщо я використовую статичний метод то приходиться все переводити на статичне(TextView, ImegaView ...), а їх дуже багато. В кінці виходить що пам'ять переповнюється якщо переходити між Activity туди і назад.
Тому повернемось до питання:
Як визначити у головному потоці що код в асинхронному потоці вже закінчив свою роботу?
або можна
Як звільнити пам'ять?

Якщо є посилання на статі то їх теж скидуйде.

Подякували: leofun011

2

Re: Асинхронна робота потоків(Android/Java)

Ви Thread.join шукаєте чи Thread.isAlive?

Подякували: ShadowTigr1

3

Re: Асинхронна робота потоків(Android/Java)

ShadowTigr написав:

...у головному потоці взнати що настала пора викликати server.getResult() для подальшої обробки

Один з варіантів - CompletableFuture

ShadowTigr написав:

Якщо є посилання на статі ...

https://www.baeldung.com/java-completablefuture

Подякували: leofun01, ShadowTigr2

4

Re: Асинхронна робота потоків(Android/Java)

koala написав:

Ви Thread.join шукаєте чи Thread.isAlive?

Обидва методи гарно справляються зі своєю роботою але не підходять до цієї задачі.
- Запускаємо інший потік
- Thread.isAlive видав true чим пітвердив запуст іншого потоку.
- Thread.join теж відправцював.
- Thread.isAlive видав false чим підтвердив що другий потік закінчився.
- А після цього прийшла відповідь сервера.

А є якийсь метод який буде постійно моніторити чи змінилося значення певного поля?

5 Востаннє редагувалося koala (25.07.2022 09:06:14)

Re: Асинхронна робота потоків(Android/Java)

Вам треба, що якийсь код було виконано в основному потоці після того, як відпрацює асинхронний виклик з download()? По завершенню завантаження викликається onResponse, тобто вам треба передати з onResponse сигнал в основний потік, що можна продовжувати виконання. Створіть семафор і передайте в download параметром. Хоча... а в якому потоці onResponse виконається? І чому не можна код, що треба виконати, прямо в onResponse занести?

Подякували: ShadowTigr1

6

Re: Асинхронна робота потоків(Android/Java)

Один з варіантів - CompletableFuture

Не зміг використати так як запросило API 24  а у мене API 21

7

Re: Асинхронна робота потоків(Android/Java)

ShadowTigr написав:

...запросило API 24  а у мене API 21

Я взагалі, "досить далекий", щодо мобільної розробки (Android) :( Але, я так розумію, що API 21 - це щось типу < Java 8. В такому випадку:

ShadowTigr написав:

...взнати що настала пора викликати ... для подальшої обробки...

Можете скористатися BlockingQueue (https://www.baeldung.com/java-blocking-queue), щоб мати почергові завдання. Аби, в залежності від своїх потреб, додавати та обробляти в потрібних потоках дані завдання.

Або скористатися варіантами, які описав, пан koala (див. вище).

Подякували: ShadowTigr1

8

Re: Асинхронна робота потоків(Android/Java)

koala написав:

І чому не можна код, що треба виконати, прямо в onResponse занести?

Теж задався цим питання. Так і зроблю. Дякую.