j2emanue
j2emanue

Reputation: 62519

android MVP - How should the network layer be called , from model?

In MVP android i believe the network layer (retrofit , volley etc) should NOT be apart of the model. But I need a firm example on how to construct the model then. Should the model be a singleton that the network layer simply creates when api call completes ?

Lets take a look at a presenter i have for my one of my activities:

    public class MainActivityPresenter implements IMainPresenterContract, Callback {

    IMainActivityViewContract view;//todo set up a weak reference to View to avoid leakage
    NewsService interactor;

    public MainActivityPresenter(IMainActivityViewContract view, NewsService interactor) {
        this.view = view;
        this.interactor = interactor;
    }


    public void loadResource() {
        interactor.loadResource();
    }


    public void onRequestComplete(final NewsEntities newsEntities) {

        view.dataSetUpdated(newsEntities.getResults());
    }

    @Override
    public void onResult(final NewsEntities newsEntities) {
        onRequestComplete(newsEntities);
    }

    public void goToDetailsActivity(Result result) {
        view.goToDetailsActivity(result);
    }
}

So my question is about the NewsService interactor parameter i am passing into the constructor. I was assuming this should be model data and not a networking service. But what should it look like then ? Currently mine looks like this:

    public class NewsService implements INewsServiceContract {

    private Gson gson;
    private Callback mCallback;


    public NewsService() {
        configureGson();
    }

    private static String readStream(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {

            String nextLine;
            while ((nextLine = reader.readLine()) != null) {
                sb.append(nextLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public void setCallBack(Callback cb) {
        mCallback = cb; // or we can set up event bus
    }

    private void configureGson() {


        GsonBuilder builder = new GsonBuilder();
        builder.excludeFieldsWithoutExposeAnnotation();
        gson = builder.create();
    }

    @Override
    public void loadResource() {
//Todo could use a loader instead help with the config change or a headless fragment
        new AsyncTask<String, String, String>() {
            @Override
            protected String doInBackground(String... params) {
                String readStream = "";
                HttpURLConnection con = null;
                try {
                    URL url = new URL("https://api.myjson.com/bins/nl6jh");
                    con = (HttpURLConnection) url.openConnection();
                    readStream = readStream(con.getInputStream());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                finally {
                    if(con!=null)
                    con.disconnect();
                }
                return readStream;
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                NewsService.this.onRequestComplete(result);


            }
        }.execute();
    }

    private void onRequestComplete(String data) {

        data = data.replaceAll("\"multimedia\":\"\"", "\"multimedia\":[]");
        news.hotels.com.sample.Model.NewsEntities newsEntities = gson.fromJson(data, NewsEntities.class);
        mCallback.onResult(newsEntities);
    }
}

so as you can see the NewsService in this case is doing the network calls. I think i should not have passed this into the presenter. But how can the model be constructed then ? who calls the NewsService ?

UPDATE: THIS QUESTION WAS a long time ago, everyone please use clean architecture approach, and let your presenter know nothing about the network layer.

Upvotes: 1

Views: 2620

Answers (1)

Amir Ziarati
Amir Ziarati

Reputation: 15087

the network calls need to be in Model layer and should be triggered from the presenter. but its the Model layer who decides where to et the data and its hidden from the Presenter layer.

I myself use an interactor class to do this that is in model layer and a presenter will use this interactor to get the data and the interactor will get the data from DB or Server regarding to the situation.

look at this sample project in my repo:

https://gitlab.com/amirziarati/Echarge

I used Dagger to do DI that may confuse you. just look at packaging and how i seperate concerns between layers.

UPDATE: I used presenter to sync data from server and DB which is WRONG. the presenter should know nothing about this proccess. I didnt recognize this problem that time.

Upvotes: 2

Related Questions