Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Obtain the process ID of a background process

by Retired on ‎11-01-2010 11:16 AM - edited on ‎11-01-2010 11:45 AM by BlackBerry Development Advisor (5,909 Views)

When an application runs on a BlackBerry® device, it is allocated a process ID by the operating system. This ID can be used in API calls relating to the inter-process communication system known as Global Events. For further information on global events, it is suggested that the following be reviewed in the BlackBerry® Java API’s javadoc documentation:

 

net.rim.device.api.system.Application.addGlobalEventListener (method)

net.rim.device.api.system.ApplicationManager.postGlobalEvent (method)

net.rim.device.api.system.GlobalEventListener (interface)

 

Obtaining the process ID for the current application is easy; either call getProcessId on the current Application object like this:

 

int pid = Application.getApplication().getProcessId();

Or use the ApplicationManager class like this:

int pid = ApplicationManager.getApplicationManager().getProcessId(ApplicationDescriptor.currentApplicationDescriptor());

But sometimes we need to obtain the process ID of some other application which may itself be running in background and the solution to this problem is less obvious.

 

To appreciate an occasion where we may need to do this, consider the following scenario; an application suite consists of several BlackBerry device applications and they all need to share data with each other at run-time and must stay in sync with respect to that data. Any one of the applications can change this data and when it changes, the other applications in the suite must be pro-actively informed. An event driven approach as provided by the global events system is ideal, and a background, automatically starting process can act as a central broker for distributing data updates to the applications in the suite. An application which changes the shared data must tell the “broker” that the data has changed and the broker must notify all other applications in the suite of the new data. As such, a simple protocol is used; applications must register with the broker process, informing it of their process ID. When an application changes the data, it posts a “data changed” event to the broker process and the broker posts events back to the other registered applications using the process IDs that were provided during registration.

 

Process IDs provided by applications when they register can be obtained by any of the two methods shown above. We could post our registration event to all applications running on the system and let them filter our events..... but we don’t want to. We want to post our events directly to the broker process. But to do this our applications need to “discover” its process ID at run-time so that it can be used in calls to postGlobalEvent such as the following:

 

ApplicationManager.getApplicationManager().

  postGlobalEvent(event_broker_process_id,

                  DATA_CHANGE,

                  this_app_process_id,

                  0,

                  the_new_data,

                  null);

 

Here’s an approach to this problem:

 

The API is able to tell us which code module(s) use a given Java class. It’s also able to tell us which applications use a code module and, if the application is running, we can obtain its process ID. So, we can use the name of one of the classes that our background event broker application comprises in the following basic steps, which have been simplified for the purposes of readability (a full solution appears at the end of this article):

 

 

// First make a Class object for the event broker application class

Class broker_class = Class.forName("com.none.fictional.broker.EventBroker");


// Now get a handle to the BlackBerry code module which uses this class

int module_handle = CodeModuleManager.getModuleHandleForClass(broker_class);


// Next, obtain an array of ApplicationDescriptor objects for each application which uses this

// code module

ApplicationDescriptor[] apps = CodeModuleManager.getApplicationDescriptors(module_handle);


// finally, iterate through the array looking for an application which has a process ID,

// indicating that it is running. In this solution we assume that there will be only one

// such application which uses the code module which includes our EventBroker class and that

// this is therefore our event broker process ID

for (int i=0;i<apps.length;i++) {

  process_id = ApplicationManager.getApplicationManager().getProcessId(apps[i]);

  if (process_id > -1) {

      return process_id;

  }

}

 

 

 

A complete implementation is as follows:

 

public int getEventBrokerProcessId() {

  int process_id = -1;

  Class broker_class;

  try {

    broker_class = Class.forName("com.none.fictional.broker.EventBroker");

  } catch (ClassNotFoundException e) {

    System.out.println("ClassNotFoundException trying to obtain EventBroker process ID");

    return process_id;

  }

  int module_handle = CodeModuleManager.getModuleHandleForClass(broker_class);

  ApplicationDescriptor[] apps = CodeModuleManager.getApplicationDescriptors(module_handle);

  for (int i=0;i<apps.length;i++) {

    process_id = ApplicationManager.getApplicationManager().getProcessId(apps[i]);

    if (process_id > -1) {

      return process_id;

    }

  }

  return process_id;

}
Comments
by Retired
on ‎10-14-2010 10:03 AM

Looks good to me Martin! Finally got my permissions sorted out!

Users Online
Currently online: 29 members 1,818 guests
Please welcome our newest community members: