android auto-language detection - android

I tried this library, suggested in one of the posts on stack overflow,
I've added the lib's jar to my build-path, but I'm not able to initialize DetectorFactory class with the languages' profiles.
this is the class handling the detection, as suggested in one of their samples:
class LanguageDetector {
public void init(String profileDirectory) throws LangDetectException {
DetectorFactory.loadProfile(profileDirectory);
}
public String detect(String text) throws LangDetectException {
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.detect();
}
public ArrayList<Language> detectLangs(String text) throws LangDetectException {
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.getProbabilities();
}
}
all languages profiles are stored under myProject/profiles.
trying to instantiate the class crashes my app without any useful message to logcat
calling the class ():
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
context = this.getActivity().getApplicationContext();
/* LanguageDetector detector = null;
try {
detector.init("/waggle/profiles");
} catch (LangDetectException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
new GetDataTask().execute(context);
}

Change the methods in LanguageDetector to static:
class LanguageDetector {
public static void init(String profileDirectory) throws LangDetectException {
DetectorFactory.loadProfile(profileDirectory);
}
public static String detect(String text) throws LangDetectException {
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.detect();
}
public static ArrayList<Language> detectLangs(String text) throws LangDetectException {
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.getProbabilities();
}
}
And use as follows:
try {
LanguageDetector.init("/waggle/profiles"); // <-- Are you sure the profiles are at this location???
} catch (LangDetectException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String detectedLanguage = null;
try {
detectedLanguage = LanguageDetector.detect("Dies ist ein Beispiel in Deutsch.");
} catch (LangDetectException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (detectedLanguage != null) {
// Implement your logic here
}

Related

Get information of object in mainactivity from class

I would like to use the information of 'result' in the XMLRPCMethod. When the thread is finished the correct data is in the result object.
This is a code snipped from my OpenerpRPC.java class.
class XMLRPCMethod extends Thread {
private String method;
private Object[] params;
private Handler handler;
public Object result;
private OpenerpRpc callBack;
public XMLRPCMethod(String method, OpenerpRpc callBack) {
this.method = method;
this.callBack = callBack;
handler = new Handler();
}
public void call() {
call(null);
}
public void call(Object[] params) {;
this.params = params;
start();
}
#Override
public void run() {
try {
result = client.callEx(method, params);
handler.post(new Runnable() {
public void run() {
try {
callBack.resultcall(result);
} catch (XMLRPCException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (final XMLRPCFault e) {
handler.post(new Runnable() {
public void run() {
Log.d("Test", "error", e);
}
});
} catch (final XMLRPCException e) {
handler.post(new Runnable() {
public void run() {
Throwable couse = e.getCause();
if (couse instanceof HttpHostConnectException) {
Log.d(TAG, "error"+uri.getHost());
} else {
Log.d("Test", "error", e);
}
Log.d("Test", "error", e);
}
});
}
}
}
My result call in the OpenerpRpc class looks like:
public void resultcall(Object result) throws XMLRPCException{
allres=result;
if (rtype.equals("login")){
//Isn't impossible cast the result var with (String) because cause crash..why?
userid=""+result;
}
if (rtype.equals("read")){
//Isn't impossible cast the result var with (String) because cause crash..why?
// userid=""+result;
}
// name of callback function to use in parent class (MainActivity) for receive data
this.parent.oerpcRec(rtype,allres);
}
This is how i can receive the data in mainactivity
#SuppressWarnings("unchecked")
public void oerpcRec(String rtype,Object res) throws XMLRPCException{
if (rtype=="login"){
connector.setModel("res.users");
Object[] Ids = {Integer.parseInt(connector.userid)};
// set here the fields you wont loads
Object[] values={"name"};
connector.Read(Ids,values);
}
if(rtype=="read"){
Object[] ret=(Object[])res;
Map<String, Object> map1 = (Map<String, Object>) ret[0];
if(ret.length > 1){
}
}
}
But how can i get this information in my mainactivity? I only get the information of the login id value. When I put a breakpoint in the thread it only goes to the function resultcall when I try to login.
...
public void onClick(View v) {
try {
//here set user and pass for login
connector.Login(USER,PASS);
Object[] ids = {31,30,28,26};
Object[] params ={"partner_id","tax_line","section_id","invoice_line"};
connector.Read(ids,params);
//get information of openERP for specific id's
} catch (XMLRPCException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Use an interface
public interface MyListener {
public void callback(Object result);
}
Your MainActivity must implement the interface
public class MyActivity extends Activity implements MyListener {
...
...
...
#override
public void callback(Object result) {
// getting the result value.
}
}
So when your thread finish, execute the callback() method:
MyListener ml;
ml.callback(result);
and the callback() method of you MainActivity will receive the object.

how to implement Pub-Sub Network with a Proxy by using XPUB and XSUB in ZeroMQ(jzmq) 3.xx

I am trying to implement using XPUB and XSUB as provided in this below figure. I have gone through their examples provided but could not get one for XPUB and XSUB in Java. Here they have given an example in C which is little complex as I am new to ZeroMQ.
I am trying to use it in android using jni wrapped version. Please help me to find an example, how to implement this Pub-Sub Network with a Proxy in ZeroMQ using java.
Currently I am referring http://zguide.zeromq.org/page:all
I have tried to port it as follows.
Subscriber.java
public class Subscriber extends Thread implements Runnable {
private static final String TAG = "Subscriber";
private Context ctx;
public Subscriber(ZMQ.Context z_context) {
this.ctx = z_context;
}
#Override
public void run() {
super.run();
ZMQ.Socket mulServiceSubscriber = ctx.socket(ZMQ.SUB);
mulServiceSubscriber.connect("tcp://localhost:6001");
mulServiceSubscriber.subscribe("A".getBytes());
mulServiceSubscriber.subscribe("B".getBytes());
while (true) {
Log.d(TAG, "Subscriber loop started..");
String content = new String(mulServiceSubscriber.recv(0));
Log.d(TAG, "Subscriber Received : "+content);
}
}
}
Publisher.java
public class Publisher extends Thread implements Runnable {
private static final String TAG = "Publisher";
private Context ctx;
public Publisher(ZMQ.Context z_context) {
this.ctx = z_context;
}
#Override
public void run() {
super.run();
ZMQ.Socket publisher = ctx.socket(ZMQ.PUB);
publisher.connect("tcp://localhost:6000");
while (true) {
Log.d(TAG, "Publisher loop started..");
publisher.send(("A Hello " + new Random(100).nextInt()).getBytes() , 0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
XListener.java (For now a simple Forwarder)
public class XListener extends Thread implements Runnable {
private static final String TAG = null;
private Socket publisherX;
private Context ctx;
private Socket subscriberX;
public XListener(ZMQ.Context ctx, ZMQ.Socket subscriberX,
ZMQ.Socket publisherX) {
this.ctx = ctx;
this.subscriberX = subscriberX;
this.publisherX = publisherX;
}
#Override
public void run() {
super.run();
while (true) {
Log.d(TAG, "XListener loop started..");
String msg = new String(subscriberX.recvStr());
Log.v(TAG, "Listener Received: " +"MSG :"+msg);
publisherX.send(msg.getBytes(), 0);
}
}
}
in application main()
private void main() {
ZMQ.Context ctx = ZMQ.context(1);
ZMQ.Socket subscriberX = ctx.socket(ZMQ.XSUB);
subscriberX.bind("tcp://*:6000");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ZMQ.Socket publisherX = ctx.socket(ZMQ.XPUB);
publisherX.bind("tcp://*:6001");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new XListener(ctx, subscriberX, publisherX).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new XSender(ctx, subscriberX, publisherX).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Subscriber(ctx).start();
new Publisher(ctx).start();
}
With the code I am not able to listen XSUB. While porting espresso.c, I was not able to find any wrapper in java bindings of ZMQ. How to implement a simple proxy or am I missing something??
Wow I'm answering my own question. I missed to add a forwarder from publisherX to subscriberX. Here is the missing code. Now XSUB and XPUB are able to send and get data.
public class XSender extends Thread implements Runnable {
private static final String TAG = null;
private Socket publisherX;
private Context ctx;
private Socket subscriberX;
public XSender(ZMQ.Context ctx, ZMQ.Socket subscriberX,
ZMQ.Socket publisherX) {
this.ctx = ctx;
this.subscriberX = subscriberX;
this.publisherX = publisherX;
}
#Override
public void run() {
super.run();
while (true) {
// Read envelope with address
Log.d(TAG, "XListener loop started..");
String msg = new String(subscriberX.recv(0));
Log.v(TAG, "Listener Received: " +"MSG :"+msg);
publisherX.send(msg.getBytes(), 0);
}
}
}

How to Display Progress Dialog for Android Robotium Test:

Main Class:
public class ProgressIndicator {
static ProgressIndicator instance;
Context context;
public static ProgressIndicator getInstance() {
if (instance == null) {
instance = new ProgressIndicator();
}
return instance;
}
private ProgressIndicator() {
}
IndicatorThread sd;
public void showIndicator(Activity activity, String title, String message, boolean flag) {
sd = new IndicatorThread(activity, title, message, flag);
sd.start();
}
public void dismissIndicator(Activity activity) throws InterruptedException{
sd.dismiss();
// sd.join();
}
private static class IndicatorThread extends Thread {
private static final Message listener = null;
private static String mTitle;
private static String mText;
private Activity mActivity;
private boolean mflag;
private ProgressDialog mDialog;
protected boolean dismiss;
IndicatorThread(Activity activity, String title, String text, boolean flag) {
super();
IndicatorThread.mText = text;
IndicatorThread.mTitle = title;
this.mActivity = activity;
this.mflag = flag;
if (mDialog == null) {
mDialog = new ProgressDialog(mActivity);
mDialog.setTitle(mTitle);
mDialog.setMessage(mText);
mDialog.setIndeterminate(true);
mDialog.setCancelable(true);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if(mflag == true){
mDialog.setButton("Cancel", listener);
mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface arg0) {
mDialog.dismiss();
interrupt();
}
});
}
}
mDialog.show();
mDialog.getWindow().setLayout(160, 350);
mDialog.getWindow().setGravity(0);
}
public void dismiss() {
dismiss = true;
mDialog.dismiss();
System.out.println("notifying..."+dismiss);
synchronized (this) {
notifyAll();
}
}
#Override
public void run() {
System.out.println("Running..."+dismiss);
while (!dismiss) {
System.out.println("waiting..."+!dismiss);
synchronized (this) {
try {
wait();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
System.out.println("Quitting...");
}
}
}
Call from AppController class:
private ProgressIndicator progressInstance = null;
public void showWaitingAnimation(Activity parent) {
progressInstance.showIndicator(AppController.getInstance().currentActivity, "" , "", false);
}
Test Class:
public class ProgressIndicatorTest extends
ActivityInstrumentationTestCase2<MyTestActivity> {
private Solo solo;
private ProgressIndicator progressIndicatorInstance;
public ProgressIndicatorTest() {
super("com.test.activity",
MyTestActivity.class);
}
protected void setUp() throws Exception {
AppController.getInstance().startApp(getActivity());
solo = new Solo(getInstrumentation(), getActivity());
progressIndicatorInstance = ProgressIndicator.getInstance();
}
protected void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
public void testGetInstance() {
try {
ProgressIndicator instance = ProgressIndicator.getInstance();
assertNotNull(instance);
} catch (Exception e) {
fail("Creation of ExceptionDetails get instance failed!");
}
}
public void testShowIndicator() {
Log.d("testCase Name:-", "testShowIndicator");
ProgressIndicator progressInstance = ProgressIndicator.getInstance() ;
progressInstance.showIndicator(AppController.getInstance().getCurrentActivity(), "" , "", false);
//AppController.getInstance().showWaitingAnimation(AppController.getInstance().getCurrentActivity());
solo.waitForDialogToClose(8000);
try {
progressInstance.dismissIndicator(AppController.getInstance().getCurrentActivity());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void testDismissIndicator() {
Log.d("testCase Name:-", "testDismissIndicator");
ProgressIndicator progressInstance = ProgressIndicator.getInstance() ;
progressInstance.showIndicator(AppController.getInstance().getCurrentActivity(), "" , "", false);
solo.waitForDialogToClose(2000);
try {
progressInstance.dismissIndicator(AppController.getInstance().getCurrentActivity());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//AppController.getInstance().showAppTerminationDialog("", AppController.getInstance().getCurrentActivity());
}
}
While running the project the dialog is visible & working properly. But while running the test case only a black screen is visible, no dialog is getting displayed (after using solo.waitForDialogToClose(8000); problem is there). No error or exception is getting thrown and the test cases are getting passed in Android Junit test. If anyone has any idea how to display this progress dialog in case of robotium test, Please share.
In my case I can successfully display progress dialogs.
I simply used
boolean showProgressBar = false;
showProgressBar = solo.waitForText("Verifying and Saving Credentials...", 1, 3000);
I hope it should also work for you.. :)

testing a class with out activity and services

this is my actual class I am writing test class below.
public class ReadFile {
private Scanner rx, tx;
public void openFile() {
try {
rx = new Scanner(new File("/sys/class/net/eth0/statistics/rx_bytes"));
tx = new Scanner(new File("/sys/class/net/eth0/statistics/tx_bytes"));
} catch (Exception e) {
e.printStackTrace();
}
}
public String readRxFile() {
String rxData = "";
while (rx.hasNext()) {
rxData = rx.next();
}
return rxData;
}
public String readTxFile() {
String txData = "";
while (tx.hasNext()) {
txData = tx.next();
}
return txData;
}
public void closeFile() {
rx.close();
tx.close();
}
}
this is test class. to test the read data.
public class Testreadrxfile extends TestCase {
public Testreadrxfile() {
super();
}
protected void setUp() throws Exception {
try {
super.setUp();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ReadFile rf;
public void testappdata() {
String str1 = rf.readRxFile();
Assert.assertEquals("14081",str1 );
}
}
this is the error I am getting.
java.lang.NullPointerException
atcom.android.deviceintelligence1. test.Testreadrxfile.testappdata(Testreadrxfile.java:26)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1448)
this is not activity or service test to use getactivity() or getservice() so what I should do to get out of this error . thanks for help in advance.
see your code.. rf is not initialised..
ReadFile rf; // not intialisd
public void testappdata() {
String str1 = rf.readRxFile(); // equivalent to null.readRxFile();
Assert.assertEquals("14081",str1 );
}
yeah, rf is not initialised. In this kind of situation first thing to do is attach the debugger on the line you are getting error, and in most cases answer becomes obvious.
UPDATE
first your code didn't work because you didn't initialised rx, now your code doesn't work becasue you never called following function. In the function you are initialising your scanner objects. call this function from your readRxFile function and you should be good to go.
public void openFile() {
try {
rx = new Scanner(new File("/sys/class/net/eth0/statistics/rx_bytes"));
tx = new Scanner(new File("/sys/class/net/eth0/statistics/tx_bytes"));
} catch (Exception e) {
e.printStackTrace();
}
}
public String readRxFile() {
String rxData = "";
while (rx.hasNext()) { //eq. to null.haxNext()
rxData = rx.next();
}
return rxData;
}

Comments on my MVP pattern for Android

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();
}
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.

Categories

Resources