Pages
Android Services
7:22 PM
Posted by Mina Samy
we need to distinguish between A Service and a Thread or an AsyncTask: Threads or Async task perform their tasks in a background thread thus they do not block the main thread, while a service performs it's work in the main thread. so if a service is performing an intensive task such as calling a web service, it may block the main thread until it finishes. So for intensive tasks a service should run it's work in a background thread.
A service runs in the same process of the application and keeps running until stopped by itself, stopped by the user or killed by the system if it needs memory.
Creating a service:
to create a service we create a class that extends android.app.Service and it would be like this:public class DemoService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}next we need to define our service in our AndroidManifest.xml file:<service android:name="DemoService"></service>The service life cycle has the following events
- onCreate(): called when the service is created.
- onStart(): Called when the service starts by a call to startService(Intent intent).
- onDestroy(): Called as the service is terminates.
Calling a service:
A service can be called from an activity in two ways:- By calling startService(Intent intent).
- By binding to the service through an Binder object.
calling startService(Intent intent):
to start a service from an activity using this method, we create an intent and start the service like this:Intent intent=new Intent(this,DemoService.class); startService(intent);the startService(intent) method causes the onStart() method of the service to be called, so the service can execute it's work like this:
public class DemoService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
doSomething();
}
public void doSomething(){
// do some work
}
}the service will keep running until it stops itself via stop stopSelf() after finishing work:@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
doSomething();
stopSelf();
}or it can be stopped from the activity via stopService(Intent intent).Binding to a service through an Binder object:
As the service runs in the same process of the application the service has only one instance (singleton) instance running. you may want to keep reference to this instance to perform periodical tasks or to call the service methods themselves.to make the service bind-able we extends Binder class and return an instance of it in the service's onBind(Intent intent) method:
public class DemoService extends Service {
private final IBinder binder = new LocalBinder();
@Override
public IBinder onBind(Intent arg0) {
return binder;
}
public class LocalBinder extends Binder {
DemoService getService() {
return DemoService.this;
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
doSomething();
stopSelf();
}
public void doSomething(){
// do something
}
}then we bind the service from our activity by first creating a ServiceConnection object to handle the service connection/disconnection then binding to the service by an intent like this:public class MainActivity extends Activity {
DemoService mService;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
ServiceConnection serviceConn=new ServiceConnection() {
/**
* service unbound, release from memory
**/
@Override
public void onServiceDisconnected(ComponentName name) {
mService=null;
}
/**
* service is bound, start it's work
**/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService=((LocalBinder)service).getService();
mService.doSomething();
}
};
@Override
protected void onResume() {
super.onResume();
// bind to the service by an intent
Intent intent=new Intent(this,DemoService.class);
// AUTO CREATE: creates the service and gives it an importance so that it won't be killed
// unless any process bound to it (our activity in this case) is killed to
bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
/ unbind the service whena ctivity is destroyed
unbindService(serviceConn);
}
}notice that we unbind the service in the activity's onDestroy() method to disconnect from the service and stop it from executing any furtherand that's was all about Android services, stay tuned for another Android tutorial.
| Reactions: |
Parsing JSON respone:
7:19 PM
Posted by Mina Samy
"persons"
[
{
"person"{
"firstName": "John",
"lastName": "Smith",
"age": 25
}
}
{
"person"{
"firstName": "Catherine",
"lastName": "Jones",
"age": 35
}
}
]this response is a JSON Array with the name "persons", this array consists of "person" JSON Objects.to parse such a reponse:
public ArrayList<Person> getMessage(String response){
JSONObject jsonResponse;
ArrayList<Person> arrPersons=new ArrayList<Person>;
try {
// obtain the reponse
jsonResponse = new JSONObject(response);
// get the array
JSONArray persons=jsonResponse.optJSONArray("persons");
// iterate over the array and retrieve single person instances
for(int i=0;i<persons.length();i++){
// get person object
JSONObject person=persons.getJSONObject(i);
// get first name
String firstname=person.optString("firstname");
// get last name
String lastname=person.optString("lastname");
// get the age
int age=person.optInt("age");
// construct the object and add it to the arraylist
Person p=new Person();
p.firstName=firstname;
p.lastName=lastname;
p.age=age;
arrPersons.add(p);
}
} catch (JSONException e) {
e.printStackTrace();
}
return arrPersons;
}notice that we used the methods optJSONArray,optString,optInt instead of using getString,getInt because the opt methods return empty strings or zero integers if no elements are found. while the get methods throw an exception if the element is not found.
| Reactions: |
Parsing XML wit SAX parser
7:10 PM
Posted by Mina Samy
Android provides org.xml.sax package that has that provides the event-driven SAX parser.
to parse the previous response with SAX parser, we have to create a class extending DefaultHandler and override the following methods:
then we call the parser like this:
to parse the previous response with SAX parser, we have to create a class extending DefaultHandler and override the following methods:
- startDocument(): invoked when the xml document is open, there we can initialize any member variables.
- startElement(String uri, String localName, String qName, Attributes attributes): invoked when the parser encounters a xml node, here we can initialize specific instances of our person object.
- endElement(String uri, String localName, String Name): invoked when the parser reaches the closing of a xml tag. here the element value would have been completely read.
- characters(char[] ch, int start, int length): this method is called when the parser reads characters of a node value.
<?xml version="1.0"?>
<person>
<firstname>Jack</firstname>
<lastname>smith</lastname>
<age>28</age>
</person>so our parsing class will be like this:/**
* SAX parser to parse persons response
*/
public class PersonParser extends DefaultHandler
{
// arraylist to store person objects
ArrayList persons;
// temporary person object
Person tempPerson;
// string builder acts as a buffer
StringBuilder builder;
/**
* Initialize the arraylist
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
pesons=new ArrayList();
}
/**
* Initialize the temp person object which will hold the parsed in//fo
* and the string builder that will store the read characters
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName.equalsIgnoreCase.equals("person")){
tempPerson=new Person();
builder=new StringBuilder();
}
}
/**
* Finished reading the person tag, add it to arraylist
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// finished reading a person, add it to the arraylist
if(localName.toLowerCase().equals("person"))
{
this.persons.add(tempPerson);
}
// finished reading "firstname" tag assign it to the temp person
else if(localName.toLowerCase().equals("firstname")){
tempPerson.firstName=builder.toString();
}
// finished reading "lastname" tag assign it to the temp person
else if(localName.toLowerCase().equals("lastname")){
tempPerson.lastName=builder.toString();
}
// finished reading "age" tag assign it to the temp person
else if(localName.toLowerCase().equals("age")){
tempPerson.age=Integer.parseInt(builder.toString());
}
}
/**
* Read the value of each tag
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// read the characters and append them to the buffer
String tempString=new String(ch, start, length);
builder.append(tempString);
}
}the code is pretty easy, the parser iterates over each node, you check the current node name and take an action.then we call the parser like this:
public ArrayList getPersons(final String response) throws ParserConfigurationException, SAXException, IOException
{
BufferedReader br=new BufferedReader(new StringReader(response));
InputSource is=new InputSource(br);
PersonParser parser=new PersonParser();
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser sp=factory.newSAXParser();
XMLReader reader=sp.getXMLReader();
reader.setContentHandler(parser);
reader.parse(is);
ArrayList persons=parser.persons;
return persons;
}| Reactions: |
Parsing XML wit DOM parser
7:05 PM
Posted by Mina Samy
- DOM Parser.
- Pull Parser.
- SAX Parser.
<?xml version="1.0"?>
<person>
<firstname>Jack</firstname>
<lastname>smith</lastname>
<age>28</age>
</person>which we need to parse to create an object from Person class:public class Person{
public String firstName;
public String lastName;
public int age;
}Parsing the response with DOM Parser:matching each node to parse the info.
to parse our example response with DOM parser, we implement a function like this
void parseByDOM(String response) throws ParserConfigurationException, SAXException, IOException{
Person person=new Person();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(response)));
// normalize the document
doc.getDocumentElement().normalize();
// get the root node
NodeList nodeList = doc.getElementsByTagName("person");
Node node=nodeList.item(0);
// the node has three child nodes
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
Node temp=node.getChildNodes().item(i);
if(temp.getNodeName().equalsIgnoreCase("firstname")){
person.firstName=temp.getTextContent();
}
else if(temp.getNodeName().equalsIgnoreCase("lastname")){
person.lastName=temp.getTextContent();
}
else if(temp.getNodeName().equalsIgnoreCase("age")){
person.age=Integer.parseInt(temp.getTextContent());
}
}
Log.e("person", person.firstName+ " "+person.lastName+" "+String.valueOf(person.age));
}The previous method is good, it retrieves the info correctly, but it requires that you are familiar with the xml structure so that you know the order of each xml node.
| Reactions: |
Subscribe to:
Posts (Atom)









