Здравствуйте. Изучаю java ee, сделал примитивную серверную часть и теперь взялся за примитивную клиентскую часть. Клиента пишу под андроид, пытаясь реализовать архитектуру MVVM
И так, приступим.
В наличии классы MainActivity, MainViewModel, ServerHandler.
Активность содержит в себе ссылку на объект mainViewModel и кнопку в onClick() которой вызов метода mainViewModel.LoadData();
MainViewModel содержит в себе объект RequestHandler и метод LoadData();
ServerHandler содержит в себе поля для работы с запросами и внутренний класс RequestExecutor implements Runnable
Задача ServerHandler - отвечать за подключение к серверу, формировать запросы, обрабатывать ответы.
Задача RequestExecutor - получать объект запроса и собственно выполнять запрос и возвращать ответ.
Для работы с Http использую OkHttp;
В общем, если не использую многопоточность то когда активность делает запрос ко viewModel за данными, а та в свою очередь пытается загрузить их из сервера то UI поток виснет до конца выполнения логики запроса.
Если использую многопоточность то когда внутри RequestExecutor получу объект Responce - буду не иметь ни малейшего понятия как мне теперь имея ответ, дать данные с ответа к viewModel и что бы после этого viewModel сказала активности, что данные пришли.
Вопрос к уважаемым знатокам: Как мне правильно реализовать операцию асинхронной передачи данных в главный поток не тормозя главный поток в MVVM?
Я начинающий в этой теме, не бросайтесь камнями, пожалуйста.
Если есть у вас варианты иной реализации - буду рад выслушать ибо не имею понятия как правильно реализовывать подобные действия.
код прилагаю.
MainActivity
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.clientapp.R;
import com.example.clientapp.viewmodel.MainViewModel;
public class MainActivity extends AppCompatActivity {
private MainViewModel viewModel;
private TextView outputText;
private ProgressBar loadingProgress;
private Button loadButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
outputText = findViewById(R.id.output_textview);
loadingProgress = findViewById(R.id.loading_progress);
loadButton = findViewById(R.id.load_button);
}
public void LoadDataOnClick(View view) {
loadButton.setEnabled(false);
loadingProgress.setVisibility(View.VISIBLE);
viewModel.LoadText();
}
}
MainViewModel
package com.example.clientapp.viewmodel;
import androidx.lifecycle.ViewModel;
import com.example.clientapp.ServerHandler;
public class MainViewModel extends ViewModel {
ServerHandler serverHandler;
public MainViewModel() {
this.serverHandler = ServerHandler.getInstance();
}
public void LoadText(){
serverHandler.loadData();
}
}
ServerHandler
package com.example.clientapp;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class ServerHandler {
private final String GET_DATA_URL = "http://192.168.8.100:8080/app";
private static ServerHandler handler;
private OkHttpClient client;
private ServerHandler() {
client = new OkHttpClient.Builder().cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(@NotNull HttpUrl url, @NotNull List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
@NotNull
@Override
public List<Cookie> loadForRequest(@NotNull HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).build();
}
public static ServerHandler getInstance() {
if (handler == null) handler = new ServerHandler();
return handler;
}
public void loadData() {
Request request = new Request.Builder()
.url(GET_DATA_URL)
.build();
Thread requestThread = new Thread(new RequestExecutor(request));
}
class RequestExecutor implements Runnable{
Request request;
public RequestExecutor(Request request) {
this.request = request;
}
@Override
public void run() {
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//What should i do here?
}
});
}
}
}