Как синхронно получать данные из разных источников (кеш устройства, веб-сервер и база данных sqlite)? - PullRequest
0 голосов
/ 05 января 2019

и с новым годом! Я изучаю разработку под Android с использованием Java, и я начал с создания своего первого приложения с использованием компонентов архитектуры , следуя этому руководству: Руководство по архитектуре приложения

Я хорошо понимаю дизайн архитектуры Android и другие основные вещи. Но у меня все еще есть проблема в обработке фоновых задач, потому что есть много классов, которые обеспечивают многопоточность, таких как: Executor , IntentService и asynctask ..

Мой код:

  • Класс репозитория:

    public class MovieRpository  {
    private IWebService m_webService;
    private Movie _movie;
    private AppExecuters m_executers;
    
    private MovieRpository(AppExecuters executers, TMDB webService){
       this.m_executers = executers;
       this.m_webService = webService;
    }
    
     private static MovieRpository m_singleInstance;
    
     public static MovieRpository getInstance(){
        if(m_singleInstance == null){
             m_singleInstance = new 
     MovieRpository(AppExecuters.getInstance(), new TMDB(new JsonParser<Movie>()));
    }
    return  m_singleInstance;
    }
    
     public LiveData<Movie> getMovie( String movieId){
       final MutableLiveData<Movie> _liveDataMovie = new MutableLiveData<Movie>();
       m_executers.networkIO().execute(()->{
           _movie =(Movie)m_webService.getObject(movieId);});
       _liveDataMovie.setValue(_movie);
       return _liveDataMovie;
      }
     }
    

Моя проблема:

В классе репозитория, когда я использую отладчик во втором потоке, который создается m_executers.networkIO () _movie имеет значение внутри сетевого потока. но это всегда нуль вне метода execute.

Остальная часть моего кода:

- Интерфейс IWebService

  public interface IWebService<T> {
    public T getObject(String url);
  }
  • TMDB:

    public class TMDB implements IWebService<Movie> {
       private JsonParser<Movie> m_jsonParser;
       private Movie _movie;
       public TMDB(JsonParser<Movie> jsonParser){
       m_jsonParser = jsonParser;
    }
    @Override
    public Movie getObject(String url) {
    
      try {
          HttpURLConnection _connection = (HttpURLConnection) (new URL(url)).openConnection();
          _connection.setRequestMethod(Settings.CONNECTION_GET_METHOD);
          _connection.setConnectTimeout(Settings.CONNECTION_TIMEOUT);
          _connection.setReadTimeout(Settings.DATA_READ_TIMEOUT);
          _connection.connect();
          InputStreamReader _streamReader = new InputStreamReader(_connection.getInputStream());
          BufferedReader _bufferedReader = new BufferedReader(_streamReader);
          StringBuilder _data = new StringBuilder();
          String _line;
          while((_line = _bufferedReader.readLine()) != null ){
              _data.append(_line);
          }
          _bufferedReader.close();
          _streamReader.close();
    
           Gson _gson = new Gson();
          _movie = _gson.fromJson(_data.toString(), Movie.class);
    
      }
      catch(MalformedURLException e) {
          e.printStackTrace();
      }
      catch(IOException e){
          e.printStackTrace();
      }
      return _movie;
      }
    }
    
  • Одноэлементный класс AppExecuters для управления потоками:

    public class AppExecuters {
    private static AppExecuters m_singltonInstance;
    private Executor m_NetworkIO;
    private Executor m_diskIO;
    private Executor m_mainThread;
    private static final Object LOCK = new Object();
    
    private AppExecuters(Executor diskThread, Executor networkThread, Executor mainThread){
        this.m_diskIO = diskThread;
        this.m_mainThread = mainThread;
        this.m_NetworkIO = networkThread;
    }
    public static AppExecuters getInstance(){
        if(m_singltonInstance == null){
            // In-order to make the singleton instance synchronized between all threads.
            synchronized (LOCK){
                m_singltonInstance = new AppExecuters(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3), new MainThread());
            }
        }
        return m_singltonInstance;
    }
    
    public  Executor networkIO(){
        return m_NetworkIO;
    }
    public  Executor diskIO(){
        return m_diskIO;
    }
    public  Executor mainThread(){
        return m_mainThread;
    }
    
    private static class MainThread implements Executor{
        private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
        @Override
        public void execute(Runnable command) {
            mainThreadHandler.post(command);
        }
    }
    

    }

  • Мне также нужно знать лучшие практики управления темы в таком случае.

...