Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Tuesday, June 26, 2012

Phonegap plugin. Fixed an issue of not getting a callback in Js after this.success() called from Plugin class

I was facing a weird problem on developing a plugin for Phonegap on Android. After the the execution of native Java function, i was not able to give back the success or failure message to JS file.

The following is how my Plugin class looks like.
public class MyPlugin extends Plugin {
  @Override
  public PluginResult execute(String action, JSONArray data, String callbackId) {
        
        this.callbackId = callbackId;
        
        /* .. some code ... */

        StartMyAsyncThread();
        
        PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
        return pr;
    }
        
    
    public void resultOfAsyncThread(String message){
        
        PluginResult pr = new PluginResult(PluginResult.Status.OK, message);
        this.success(pr, this.callbackId)
    }
    
}


From the execute class, if I returned Status.OK instead of Status.NO_RESULT, I was able to get the call to success_callback function in javascript file. But, from the asynchronous thread, if I called this.success(), I was not getting the call to success_callback function in javascript.

This was crucial as it is the only way i can get the result of native calls to the javascript.

After hours of trial and error and googling, I got the fix. I added the call  pr.setKeepCallback(true); after creating the PluginResult object. And everything seems to be going fine.

This is how my modified code looks now.

public class MyPlugin extends Plugin {

  @Override
  public PluginResult execute(String action, JSONArray data, String callbackId) {
        
        this.callbackId = callbackId;
        
        /* .. some code ... */

        StartMyAsyncThread();
        
        PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
        pr.setKeepCallback(true);
        return pr;
    }
        
    
    public void resultOfAsyncThread(String message){
        
        PluginResult pr = new PluginResult(PluginResult.Status.OK, message);
        pr.setKeepCallback(true);
        this.success(pr, this.callbackId)
    }
    
}


I got the fix from this stackoverflow post.

Sunday, June 10, 2012

UIViewController in iOS vs Activity in Android

There is an empty container that acts parent to all the views on a screen. This container is invisible, but this is where you add the root View. This container act as a controllers, where you can receive the events from its Views and and also control the lifecycle of a View.
Usually each of these controllers use to perform independent functionality. Thus to invoke a functionality, for example to take a picture, a controller is invoked.

In Android, this is known as Activity, whereas in iPhone it is called UIViewController.

Following are few similarities between Activity and UIViewController

Feature in iOS in Android
Setting root View calls function 
[UIViewController setView:View]
calls function
Activity.setContentView(View)
Setting root View from xml The function initWithNibName:bundle: automatically takes the xib file matching the same name of the controller to load the View. If we want to mention a file with different name it can be mentioned as an argument in this function.   Inside the function onCreate() uses function Activity.setContentView(int) to set the view form xml. The View are defined in xml in ''Resource" folder
Callbacks to handling Lifecycle. (Different stages in the controller lifecycle is handled by deferent callbacks)
viewDidLoad:
viewWillUnload:
viewDidUnload:

viewWillAppear:
viewDidAppear:
viewWillDisappear:
viewDidDisappear:

onStart();
onRestart();
onResume();
onPause();
onStop()l
onDestroy();
Invoking counterpart using presentViewController:animated:completion: Using Intent

This docent mean that UIViewController and Activities are similar in all respect, but I just pointed out some similarity. To mention a difference, here is one.

An Activity in Android cannot hold an sub Activity. Where as in iOS, a UIViewController can hold another UIViewController.

That is, a parent-child relationship exist for UIViewController in iOS. UITabViewController and UINavigationViewController  are the example of a parent View Controllers. On a parent child relationship, the View of a child controller is usually shown inside the parent controllers view.

There is also another type of relationship, the presenter-presentee relationship. Here a UIViewController invoke a different UIViewController that is not its child. Usually, the View of the invoked UIViewController   covers the view of the UIViewController that invoked it.  Also in the presenter-presentee relationship, the controllers docent shares any common data.

Activity in Android support only presenter-presentee relationship. An activity can invoke another activity using an Intent.