Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comments on my MVP pattern for Android

Tags:

android

mvp

I am planning to use MVP pattern for my new Android project. I have done some sample code and I would like to know, have I implemented it correctly? Please give comments on the code and also post your suggestions.

my activity class I am extending it from my BaseView class and I am implementing an interface. this activity simply calls an webservice in a new thread and updates the value in the textview.

public class CougarTestView extends BaseView implements ICougarView,
        OnClickListener {
    CougarTestPresenter _presenter;
    public String activityName = "CougarHome";

    /** Called when the activity is first created. */`enter code here`
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState, activityName);
        setContentView(R.layout.main);
        _presenter = new CougarTestPresenter(this);
        getSubmitBtn().setOnClickListener(this);
        getCallInfoBtn().setOnClickListener(this);

    }

    private Button getCallInfoBtn() {
        return (Button) findViewById(R.id.btn_callinfo);
    }

    public void setServiceValue(String retVal) {
        // TODO Auto-generated method stub
        getResultLabel().setText(retVal);
        setPbar(false);
        // toastMsg(retVal);
    }

    public void ResetPbar() {
        getProgressBtn().setProgress(0);
    }

    public void setProcessProgress(int progress) {

        if (getProgressBtn().getProgress() < 100) {
            getProgressBtn().incrementProgressBy(progress);
        } else {
            setPbar(false);
        }
    }

    private TextView getResultLabel() {
        return (TextView) findViewById(R.id.result);
    }

    private Button getSubmitBtn() {
        return (Button) findViewById(R.id.btn_triptype);
    }

    private ProgressBar getProgressBtn() {
        return (ProgressBar) findViewById(R.id.pgs_br);
    }

    public void setPbar(boolean visible) {
        if (!visible) {
            getProgressBtn().setVisibility(View.GONE);
        } else
            getProgressBtn().setVisibility(View.VISIBLE);
    }

    @Override
    public void setHttpResult(String retVal) {
        // TODO Auto-generated method stub
        setServiceValue(retVal);
    }

    private void toastMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.btn_triptype: {           
            try {
                _presenter.valueFromService(RequestType.CallInfo, 0);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        }

        default:
            setServiceValue("default");
        }
    }


}

My activity class: in my activity class i am having a textview and a button. when i press the button , it call the webservice to get the data in the presenter class. the presenter class calls the webservice parses the response and sets the value in the textview of the activity.

My presenter class


public class CougarTestPresenter {
    ICougarView mIci;
    RequestType mRtype;
    public String result= "thisi s result i";
    Handler mHandle;


    public CougarTestPresenter(ICougarView ici) {
        mIci = ici; 

    }
    public void valueFromService(RequestType type, int x) throws Exception{
        String url = getURLByType(type);

        // GetServiceresult service = new GetServiceresult();
        // service.execute(url);
        Handler handle = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {

                case Globals.IO_EXPECTION: {
                    Toast.makeText(mIci.getContext(), msg.toString(),
                            Toast.LENGTH_LONG).show();
                    NetworkConnectivityListener connectivityListener = NetworkConnectivityListener
                            .getInstace();
                    mHandle = CustomHandler.getInstance(mIci.getContext(),
                            connectivityListener, mIci);
                    connectivityListener.registerHandler(mHandle,
                            Globals.CONNECTIVITY_MSG);
                    connectivityListener.startListening(mIci.getContext());
                    mIci.setPbar(false);
                }
                    break;
                case Globals.RHAPSODY_EXCEPTION:{   
                    ExceptionInfo exInfo =null;
                        try {
                            exInfo = Utility.ParseExceptionData(msg.obj.toString());

                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                       
                        mIci.setServiceValue(exInfo.Message + exInfo.Type +exInfo.Detail);

                //      new HandleRhapsodyException(mIsa, exInfo);
                }
                break;
                default: {
                    Toast.makeText(mIci.getContext(), msg.toString(),
                            Toast.LENGTH_LONG).show();
                    mIci.setServiceValue(msg.obj.toString());
                }
                }

            }
        };

        ServiceResult thread = new ServiceResult(handle, url);
        mIci.setPbar(true);
        thread.start();

    }

    public String getURLByType(RequestType type) {
        // TODO Auto-generated method stub
        switch (type) {
        case CallInfo: {
            return ("www.gmail.com");
        }
        case TripType: {
            return ("www.google.com");
        }
        default:
            return ("www.cnet.com");

        }
    }

    private class ServiceResult extends Thread {
        Handler handle;
        String url;

        public ServiceResult(Handler handle, String url) {
            this.handle = handle;
            this.url = url;
        }

        public void run() {
            sendExceptionLog(handle);

        }
    }

    public void sendExceptionLog(Handler handle) {

        DebugHttpClient httpClient = new DebugHttpClient();

        HttpGet get = new HttpGet(
                "https://192.168.194.141/TripService/service1/");
        try {
            HttpResponse response = httpClient.execute(get);

            HttpEntity r_entity = response.getEntity();
            String xmlString = EntityUtils.toString(r_entity);
            // setdvrid.setText(xmlString + " "
            // + response.getStatusLine().getStatusCode());

            httpClient.getConnectionManager().shutdown();

            if (response.getStatusLine().getStatusCode() != 200) {
                handle.sendMessage(Message.obtain(handle, Globals.RHAPSODY_EXCEPTION,
                        xmlString));
            result= Utility.ParseExceptionData(xmlString).Message;
            }
            else
            {
                handle.sendMessage(Message.obtain(handle, Globals.SERVICE_REPONSE,
                        response.getStatusLine().getStatusCode()
                                + response.getStatusLine().getReasonPhrase()
                                + xmlString));
            }

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            handle.sendMessage(Message.obtain(handle, Globals.OTHER_EXPECTION,
                    e.getMessage().toString() + "she"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            handle.sendMessage(Message.obtain(handle, Globals.IO_EXPECTION, e
                    .getMessage().toString() + "he"));
        } catch (Exception e) {
            handle.sendMessage(Message.obtain(handle, Globals.OTHER_EXPECTION,
                    e.getMessage().toString() + "it"));
        }

    }

the below interface is implemented in the activity class and the instance of the activity class is sent as interface object to the constructor of the presenter class.

my view interface

public interface ICougarView {
public void setServiceValue(String retVal);
public void setProcessProgress(int progress);
public void setPbar(boolean b);
public void ResetPbar();
public Context getContext();
}
like image 605
Pandiarajan Subramani Avatar asked Sep 22 '11 17:09

Pandiarajan Subramani


1 Answers

Sorry for the late :) I've use MVP on Android this way.

Activities are presenters. Every presenter has a link to model(s) (sometimes it is services, sometimes not, depending from the task) and to view(s). I create custom view and set it as the content view for activity.

See:

public class ExampleModel {
   private ExampleActivity presenter;

   public ExampleModel(ExampleActivity presenter) {
       this.presenter = presenter;
   }
   //domain logic and so on
}

public class ExampleActivity extends Activity {
   private ExampleModel model;
   private ExampleView view;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       model = new ExampleModel(this);
       view = new ExampleView(this);
       setContentView(view);
   }
   // different presenter methods
}

public class ExampleView extends LinearLayout {

    public ExampleView(Context context) {
        super(context);
    }
}

Also, I've discussed this topic here.

I should warn you, that Activity shouldn't be considered as the view. We had very bad expirience with it, when we wrote with PureMVC which considered Activity as view component. Activity is excellently suitable for controller/presenter/view model (I've tried all of them, I like MVP the most), it has excellent instrumentation for managing the views (View, Dialog and so on) while it's not a view itself.

like image 58
QuickNick Avatar answered Sep 28 '22 20:09

QuickNick